monadic评估中的`bind`运算符

时间:2017-11-26 13:26:31

标签: scheme monads

我已经阅读了几次the article of Dan Friedman about monadic evaluation在Scheme中实施的内容,我对State monad子章节末尾的练习感到不安。

文章非常明确,人们通过做最小的理论获得了深刻的理解,但这种练习确实很模糊。我担心我会错过一些重要的方面,这就是我在这里问的原因。

练习是这样的:

  

在remberevensXcountevens中,增量发生在尾递归调用之前,但我们是免费的   重新排序这些事件。通过让续集的主体成为实现这个重新排序的事件变体   绑定状态的第一个参数,并对续集进行适当的调整。这是新的第一个论点   绑定状态尾调用?

它要求先从>>=运算符调用续集,然后调用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 个答案:

没有答案