更新 Link to heading
几年后再回顾,发现当时编写的内容大量是错的,因此重写。
起因 Link to heading
学习 CPS 实现过程中对单子的思考。
说明 Link to heading
ConT 主要的优点在于可以传递计算结果,和 monad 下用 lambda 传递不同,这个传递是可以显示中断的。因为单子约束的是 Monad (Cont r),a 每次计算输入的值,也就是上一次计算的结果值,对最后一层则就是输出的结果,而中间传递的是最后做为输出时计算的最后一步。
以 Monad Maybe 为对比,后续计算的 lambda 是当前 bind 的分支,由当前 bind 处理完(前一次计算)输入后调用。实际逻辑与过程式相似,很直观。
Cont 是通过 lambda 包装来实现的。不同于 Monad 的逻辑,它是将当前操作包进一个新 lambda 里,由新的调用者来接收这一参数。对于后续计算 lambda 的编写来说,与 monad 是一样,都是接受一个参数。但因为其包装方式的不同,可以对每次重新包装时的 lambda 做修改。callCC 就是在这样的前题下,通过重新包装的 lambda,来忽略传入的值,仅返回指定的值,就可以绕过后续所有的计算。
其实 Monad (Cont r) 与正常的 monad 是一样的,关键在于 callCC 的重新包装与 lambda 配合产生了提前结束的效果。与 Reader 的 ask 和 State 的 set 等是同样的手法。
参考 wiki已经做到比较好的说明。这里只是扩展一下自己的理解。