gwi*_*man 13 monads haskell computation
在阅读monads时,我一直看到像"Xyz monad中的计算"这样的短语.计算"在某个monad中"是什么意思?
我认为我对monad的含义有一个公平的把握:允许计算产生通常是某种预期类型的输出,但可以替代地或另外地传达一些其他信息,例如错误状态,记录信息,状态等,以及允许这种计算被链接.
但我不知道计算如何被称为"在"monad中.这只是引用产生monadic结果的函数吗?
示例:(搜索"计算中")
J. *_*son 11
这只是引用产生monadic结果的函数吗?
是的,简而言之.
总之,它是因为Monad
允许你将值注入(通过return
),但一旦进入Monad
它们就会被卡住.您必须使用某些功能,evalWriter
或者使用runCont
哪种功能,而不是Monad
将值返回"out".
更重要的是,Monad
(实际上,它的合作伙伴Applicative
)是拥有"容器"并允许计算在其中发生的本质.这就是(>>=)
给你的东西,能够"内部"进行有趣的计算Monad
.
因此,Monad m => m a -> (a -> m b) -> m b
让你可以计算周围和周围的内容Monad
.Monad m => a -> m a
让你注入的功能Monad
.类似的功能m a -> a
会让你"逃脱" Monad
除了它们一般不存在(仅在特定的情况下).因此,为了对话,我们喜欢谈论具有结果类型的函数,例如Monad m => m a
"在monad中".
C. *_*ann 11
通常,"monad中的计算"不仅意味着返回monadic结果的函数,而且意味着在do
块内使用的这种函数,或者作为第二个参数的一部分(>>=)
,或者等同于那些的任何其他函数.区别与您在评论中说的内容相关:
在从输入monad中提取val之后,在结果被包装为monad之前,func f中出现"Computation".我不知道计算本身是如何"在"monad中的; 它似乎明显地"出"了monad.
这并不是一个糟糕的思考方式 - 事实上,do
符号鼓励它,因为它是一种方便的方式来看待事物 - 但它确实会导致一种略带误导的直觉.没有任何东西可以从monad中"提取出来".要了解原因,请忘记(>>=)
- 这是一个支持do
表示法的复合操作.monad的更基本定义是三个正交函数:
fmap :: (a -> b) -> (m a -> m b)
return :: a -> m a
join :: m (m a) -> m a
Run Code Online (Sandbox Code Playgroud)
...... m
monad 在哪里?
现在想想如何实现(>>=)
这些:首先是类型的参数m a
和a -> m b
,你唯一的选择是使用fmap
来获得类型的东西m (m b)
,之后就可以使用join
扁平化嵌套"层"得到公正m b
.
换句话说,没有任何东西被从"monad"中"取出" - 而是将计算视为更深入到monad中,连续的步骤被折叠成monad的单个层.
请注意,从这个角度来看,monad定律也更简单 - 基本上,他们说join
只要嵌套顺序被保留(一种相关性的形式)并且引入的monadic层return
什么都不做,它们在应用时无关紧要( ()的身份价值join
.