Scheme 一元求值中的bind算子
我已经阅读了几次Scheme中的实现,我对Scheme 一元求值中的bind算子,scheme,monads,Scheme,Monads,我已经阅读了几次Scheme中的实现,我对State monad分章末尾的练习感到困扰 这篇文章很清楚,一个人通过实践获得了深刻的理解,最低限度的理论,但这个练习真的很模糊。恐怕我错过了一些重要的方面,这就是为什么我在这里问 这项工作是: 在remberevensXcountevens中,增量发生在尾部递归调用之前,但我们是自由的 重新安排这些事件的顺序。通过让续集的主体成为 第一个论点是约束状态并对续集进行适当调整。这是新的第一个论点吗 绑定一个尾部调用 它要求首先从>=操作符调用sequel
State monad
分章末尾的练习感到困扰
这篇文章很清楚,一个人通过实践获得了深刻的理解,最低限度的理论,但这个练习真的很模糊。恐怕我错过了一些重要的方面,这就是为什么我在这里问
这项工作是:
在remberevensXcountevens中,增量发生在尾部递归调用之前,但我们是自由的
重新安排这些事件的顺序。通过让续集的主体成为
第一个论点是约束状态并对续集进行适当调整。这是新的第一个论点吗
绑定一个尾部调用
它要求首先从>=
操作符调用sequel,然后调用作为参数传递给bind的ma
我不知道如何首先进行递归调用,然后调用改变状态值的ma
。我只是切换了>=
的参数,但没有切换求值顺序
如果我首先尝试评估续集
,我不知道要传递什么值
我的代码是这样的:
(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)
原始函数是
...
(bind (λ (s) `(_ . ,(add1 s)))
(λ (_) (remberevensXcountevens d)))
...
现在,首先要做的是让续集的主体(rXc d)成为第一个需要绑定的参数。
所以我们有
(bind (remberevensXcountevens d)
(λ (d) ...))
注意,我们需要d来保持递归调用的结果
我们知道我们有一个偶数,我们必须在州里加1
(bind (remberevensXcountevens d)
(λ (d) (... (λ (s) (cons '_ (add1 s))) ...)))
(λ(s)…)是没有纯值的单子。我们需要绑定它,使其成为我们计算的一部分。
所以
现在状态更新了,我们有了一个方便的纯值。自然是这样的:
(bind (remberevensXcountevens d)
(λ (d) (bind (λ (s) (cons '_ (add1 s)))
(λ (_) (unit d)))))
原始函数是
...
(bind (λ (s) `(_ . ,(add1 s)))
(λ (_) (remberevensXcountevens d)))
...
现在,首先要做的是让续集的主体(rXc d)成为第一个需要绑定的参数。
所以我们有
(bind (remberevensXcountevens d)
(λ (d) ...))
注意,我们需要d来保持递归调用的结果
我们知道我们有一个偶数,我们必须在州里加1
(bind (remberevensXcountevens d)
(λ (d) (... (λ (s) (cons '_ (add1 s))) ...)))
(λ(s)…)是没有纯值的单子。我们需要绑定它,使其成为我们计算的一部分。
所以
现在状态更新了,我们有了一个方便的纯值。自然是这样的:
(bind (remberevensXcountevens d)
(λ (d) (bind (λ (s) (cons '_ (add1 s)))
(λ (_) (unit d)))))
丹问我你的答案是不是很好——是的,非常好,事实上,在我看到你的答案后,我终于明白了丹的意思。谢谢。丹问我你的答案是否好——是的,非常好,事实上,在我看到你的答案后,我终于明白了丹的意思。谢谢