2017-11-26 23 views
1

the article of Dan Friedman about monadic evaluation을 Scheme에서 구현 한 적이 있는데, State monad의 서브 찬 종말에서 연습 문제로 골머리를 앓고 있습니다.모나드 평가에서`bind` 연산자

이 기사는 매우 명확합니다. 최소한의 이론으로 깊은 이해를 얻지 만,이 운동은 실제로는 모호합니다. 나는 몇 가지 중요한 부분을 그리워하고 이것이 내가 여기서 묻는 이유입니다.

운동

이렇게이다 : remberevensXcountevens에서

는 증가 꼬리 재귀 호출하기 전에 발생하지만, 우리는 이러한 이벤트를 재정렬 할 무료입니다. 후속 본문을 첫 번째 인수로 설정하여 상태를 바인딩하고 속편을 적절하게 조정함으로써이 재정렬 이벤트 변형을 구현합니다. 이 새로운 첫 번째 인수 이 꼬리 호출을 상태로 바인딩합니까?

IT는 >>= 조작자로부터 제 속편 호출을 한 후 결합하는 인자로 전달 ma 전화 묻는다.

재귀 호출을 먼저 발생시킨 다음 그 값을 변경하는 ma을 호출하는 방법을 이해하지 못합니다. 방금 >>=의 인수를 전환했지만 평가 순서는 전환하지 않았습니다.

먼저 sequel을 평가하려고하면 value을 전달할 수 없습니다.

내 코드는 그래서입니다 :

(define return 
    (lambda (a) 
    (lambda (s) 
     (cons a s)))) 

(define >>= 
    (lambda (sequel ma) 
    (lambda (s) 
     (let ((pair (ma s))) 
     (let ((value (car pair)) 
       (state (cdr pair))) 
      (let ((mb (sequel value))) 
      (mb state))))))) 

(define rember/count 
    (lambda (l) 
    (cond ((null? l) (return '())) 
      ((list? (car l)) 
      (>>= (lambda (a) 
        (>>= (lambda (d) 
         (return (cons a d))) 
         (rember/count (cdr l)))) 
       (rember/count (car l)))) 
      ((even? (car l)) 
      (>>= (lambda (_) (rember/count (cdr l))) 
       ;; here I want to evaluate the addition AFTER the `(rember/count (cdr l))`. 
       (lambda (s) (cons '_ (+ 1 s))))) 
      (else 
      (>>= (lambda (d) 
        (return (cons (car l) d))) 
       (rember/count (cdr l))))))) 

((rember/count '(1 2 3 4 (7 8 9 10 11) 5 6)) 0) 

답변

0

원시 기능은 이제

... 
    (bind (λ (s) `(_ . ,(add1 s))) 
       (λ (_) (remberevensXcountevens d))) 
... 

이다, 할 첫번째 일은 이 속편 (RXC d 개)의 몸을 가지고있다, 을 Y 인드하는 첫 x 째 인수가됩니다. 그래서 우리는 우리가 주위에 재귀 호출의 결과를 유지하기 위해 D가 필요

(bind (remberevensXcountevens d) 
     (λ (d) ...)) 

참고 있습니다.

우리는 짝수 인 것을 알고 있습니다. 우리는 상태에 add1을해야합니다.

(bind (remberevensXcountevens d) 
     (λ (d) (... (λ (s) (cons '_ (add1 s))) ...))) 

(λ (s) ...)은 순수한 값이없는 모나드입니다. 그것을 계산에 포함시키기 위해 바인딩해야합니다. 그래서

(bind (remberevensXcountevens d) 
     (λ (d) (bind (λ (s) (cons '_ (add1 s))) 
        (λ (_) ...)))) 

는 지금 상태가 업데이트됩니다 우리는 편리한 순수한 가치를 가지고있다. 그것은 자연스럽게 다음과 같습니다 :

+0

댄은 당신의 대답이 좋았는지 물었습니다 - 예, 정말 좋았어요. 실제로 당신의 대답을보고 난 후에 마침내 거기에서 무슨 뜻인지 이해했습니다. 감사. – alinsoar