私はSchemeで実装されたthe article of Dan Friedman about monadic evaluationを数回読みましたが、State monad
のサブチャプターの終わりからエクササイズに悩まされています。モナド評価の `bind`演算子
この記事は非常にはっきりしていますが、最小限の理論で深い理解を得ていますが、この演習は実際にはあいまいです。私はいくつかの重要な面を欠場することが恐れており、これが私がここで尋ねる理由です。
運動がそうである:
remberevensXcountevensで、増分は末尾再帰呼び出しの前に行われますが、我々は、これらのイベントの順序を変更する 自由です。続編の本文を 第1引数にして状態を束縛し、続編を適切に調整することによって、この並べ替えられたイベントの変種を実装してください。この新しい最初の引数 は、テールコールを状態にバインドしますか?
それはバインドする引数として渡さ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