这可能有助于看到一个C m a
其实只是一个计算 - 在一个抽象的Action m
类型 - 的a
在延续传递风格(a -> Action m) -> Action m
表示,这样的数据构造C
和相应的记录选择apply
只是语法起毛。没有它们而没有明确的monad实例重写,你会得到以下等效代码。 (请注意,类型Cnt
这里只是的延续,而不是延续单子在Control.Monad.Trans.Cont
延续单子更像是我的CPS
类型。)
type Cnt m a = (a -> Action m) -- a continuation, not a Cont monad
type CPS m a = Cnt m a -> Action m
bind :: CPS m a -> (a -> CPS m b) -> CPS m b
cps_a `bind` a_to_cps_b = \cont_b -> cps_a (\a -> a_to_cps_b a cont_b)
或稍微详细:
cps_a `bind` a_to_cps_b =
\cont_b -> cps_a (\a -> let cps_b = a_to_cps_b a in cps_b cont_b)
这是如何工作的?那么,括号内的部分有一个自由变量cont_b
这是一个b
- 继续;但是,给出了这个延续,它只是一个a
-继续,它使用a_to_cps_b
来构造一个b
-computation(以CPS风格),它被应用于免费的cont_b
延续。简而言之,括号中的部分是提供的a_to_cps_b
包装在一个a
- 续。与cps_a
结合起来,我们只是运用cps_a
这a
-continuation,并将代表a
-computation通过cps_a
与产生一个b
-computation地图a_to_cps_b
代表的组合,在CPS与自由变量b_cont
都表示。通过这个自由变量抽象给我们我们需要的CPS m b
。
我认为这可能有助于使整个事情更容易理解,你现在可以回到原来的定义,认识到\a -> apply (f a) k
是一个真正的a
-continuation版本的f :: a -> C m b
中的自由变量k
来表达代表b
- 续。 apply m
可用于应用a
-computation m
这个a
-continuation,和我们留下的东西,从a
结合a
-computation m
与地图f
到b
-computation,都表示在一个方面免费b
- 继续名为k
,我们可以使用lambda-abstract来构造所需的b
- 计算器,该计算器应该返回绑定操作符。