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