Haskell 可怜的人,理解monad实例吗?

Haskell 可怜的人,理解monad实例吗?,haskell,monads,continuations,Haskell,Monads,Continuations,我正在浏览《并发实现指南》,但在理解此monad实例时遇到了问题: data Action m = Atom (m (Action m)) | Fork (Action m) (Action m) | Stop newtype C m a = C {apply :: (a -> Action m) -> Action m} instance Monad (C m ) where m >>= f = C $ \k -> apply m(\a -&

我正在浏览《并发实现指南》,但在理解此monad实例时遇到了问题:

data Action m = Atom (m (Action m)) | Fork (Action m) (Action m) | Stop

newtype C m a = C {apply :: (a -> Action m) -> Action m}

instance Monad (C m ) where
 m >>= f         = C $ \k -> apply m(\a -> apply (f a) k) --?
 return x        = C $ \k -> k x

我理解延续单子的基本用法,但我正在努力破解这个声明中发生了什么

我们可以看到,
cma
实际上只是一个计算,在一个抽象的
Action m
类型上,一个
a
以连续传递样式
(a->Action m)->Action m
表示,因此,数据构造函数
C
和相应的记录选择器
apply
只是语法上的漏洞。在没有它们和显式monad实例的情况下重写,您将得到以下等效代码。(请注意,这里的类型
Cnt
只是一个延续,而不是延续单子。Control.monad.Trans.Cont中的延续单子更像我的
CPS
类型。)

或者更详细一点:

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
-计算(cps样式),应用于免费的
延续。简言之,括号中的部分是所提供的
a_至
,用
a
-续篇包装起来。为了将其与
cps\u a
相结合,我们只需将
cps\u a
应用于该
a
延拓,它表示由
cps\u a
表示的
a
-计算与产生
b
计算的映射
a\u-To\u-cps\u-b
的组合,所有都用CPS表示,带有一个自由变量
b_cont
。对这个自由变量进行抽象,可以得到我们需要的
CPS mb


我认为这可能有助于使整个事情更容易理解,现在您可以回到原始定义,认识到
\a->apply(fa)k
实际上是
f::a->cmb
a
延拓版本,用表示
b
延拓的自由变量
k
表示
apply m
可用于将
a
-计算
m
应用于此
a
-延续,剩下的是将
a
-计算
m
与从
a
b
计算的映射相结合的东西,所有这些都表示为名为
k
的自由
b
-连续,我们可以对其进行lambda抽象,以构造所需的
b
-计算,bind操作符应返回该计算

我们可以看到,
cma
实际上只是一个计算,在一个抽象的
Action m
类型上,一个
a
以连续传递样式
(a->Action m)->Action m
表示,因此,数据构造函数
C
和相应的记录选择器
apply
只是语法上的漏洞。在没有它们和显式monad实例的情况下重写,您将得到以下等效代码。(请注意,这里的类型
Cnt
只是一个延续,而不是延续单子。Control.monad.Trans.Cont
中的延续单子更像我的
CPS
类型。)

或者更详细一点:

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
-计算(cps样式),应用于免费的
延续。简言之,括号中的部分是所提供的
a_至
,用
a
-续篇包装起来。为了将其与
cps\u a
相结合,我们只需将
cps\u a
应用于该
a
延拓,它表示由
cps\u a
表示的
a
-计算与产生
b
计算的映射
a\u-To\u-cps\u-b
的组合,所有都用CPS表示,带有一个自由变量
b_cont
。对这个自由变量进行抽象,可以得到我们需要的
CPS mb

我认为这可能有助于使整个事情更容易理解,现在您可以回到原始定义,认识到
\a->apply(fa)k
实际上是
f::a->cmb
a
延拓版本,用表示
b
延拓的自由变量
k
表示
apply m
可用于将
a
-计算
m
应用于此
a
-延续,剩下的是将
a
-计算
m
与从
a
b
计算的映射相结合的东西,所有这些都表示为名为
k
的自由
b
-连续,我们可以对其进行lambda抽象,以构造所需的
b
-计算,bind操作符应返回该计算