Monad在非
可能重复:
什么是monad?
你如何用非编程术语来描述monad? 编程之外还有一些概念/东西(除了所有的编程之外,不仅仅是FP)可以说是采取行动还是以一种重要的方式呈现monad?
这是我目前的刺伤:
Monad是水桶旅:
>>=
操作)。 return
操作仅仅是将东西放入存储桶中的操作。 >>
)操作的情况下,桶的内容在被传递给下一个人之前被转储。 下一个人不在乎桶里的东西,他们只是在等待接收它。 ()
的monad,一张票正在桶内传递。 它被称为“单元”,它只是一张白纸。 希望这可以帮助。 :-)
编辑:我感谢你的支持,但可悲的是,Monad教程的诅咒再次袭来。 我所描述的只是带容器的函数应用,而不是monad! 但我不是虚无主义者 - 我相信Monad教程诅咒可能会被破坏! 所以这里有一个更多,更复杂的图片,我认为它更好一点。 你决定是否值得带给你的朋友。
Monads是一个有项目经理的桶式旅。 项目经理除了这个旅的第一个成员外,其他所有人都站在后面。 桶旅的成员坐在凳子上,并在他们面前有水桶。
第一个人收到一些东西,做一些事情,并把它放在一个桶里。 那个人然后交出来 - 而不是去大队的下一个人,那太容易了! :-) - 但是给站在那个人后面的项目经理。
项目经理(她的名字是绑定,或者是>>=
)接受了这个桶并决定如何处理它。 她可能会决定把第一个人的东西从桶中拿出来,然后把它交给在她面前的人,不要紧张(这就是IO monad)。 她可能会选择扔掉水桶并结束旅(这是fail
)。 她可能会决定绕过她面前的那个人,并且毫不犹豫地将这个桶传给旅中的下一位经理(这就是Maybe
monad中Nothing
的情况)。 她甚至可能决定把这些东西从桶里拿出来,一次递给她面前的人! (这就是List monad。)在序列( >>
)的情况下,她只是点击她面前的人的肩膀,而不是交给他们任何东西。
当下一个人制造一桶东西时,该人将其交给下一个项目经理。 下一位项目经理再次指出如何处理她给予的桶,并将桶中的东西交给她的人。 最后,这个桶被传回了项目经理链,他们可以选择使用桶来完成任务(比如List
monad组装所有结果)。 第一个项目经理产生了一堆东西。
在do
语法的情况下,每个人实际上是一个在现在所有事物的上下文中定义的操作 - 就好像项目经理不仅传递了桶中的内容,而且传递了值(呃,东西),这是由该旅以前的成员所产生的。 在这种情况下,如果使用绑定和序列而不是使用do
语法写出计算,则在这种情况下构建上下文会更容易看到 - 请注意,每个连续的“语句”都是在该点之前的操作中构建的匿名函数。
()值,IO monads和return
操作保持如上所述。
“但这太复杂了,为什么人们不能自己卸下水桶?” 我听到你问。 那么,项目经理可以在幕后做一些工作,否则这些工作会变得复杂。 我们试图让这些旅成员轻松一点,所以他们不必做太多。 例如,在Maybe monad的情况下,每个人都不必检查他们给予的价值,看他们是否没有给予 - 项目经理为他们照顾。
“那么,如果你真的想让每个人的工作变得更简单,那么为什么不能一路走下去 - 一个人只是拿东西交出东西,让项目经理担心这个问题呢?” 这通常是完成的,它有一个特殊的名字叫解除人(呃,操作)到monad中。 然而,有时候,你需要一个有点复杂的人,他们需要对生产的桶进行一些控制(比如他们是否需要在Maybe
monad的情况下返回Nothing
),这就是monad完全一般性规定。
要点是:
因此,结束我的睡前教程。 :-P
是的,编程之外有几件事情可以说是像单子一样。 不,他们都不会帮助你理解单子。 请阅读抽象,直觉和“monad教程谬误”:
Joe Haskeller正在尝试了解单子。 在努力了解他们一个星期,看例子,编写代码,阅读其他人写的东西之后,他终于有了一个“aha!”时刻:一切都突然变得清晰了,而Joe也了解Monads! 当然,真正发生的事情是,Joe的大脑已经把所有的细节融合到了更高层次的抽象中,这是Joe可以用来直观地理解monad的一个比喻; 让我们假设乔的比喻是,Monads就像卷饼一样。 乔在这里严重误解了他自己的思维过程:“当然!”乔想。 “现在这一切都很简单。 理解monad的关键是它们就像卷饼一样。 “如果以前我只是想到这一点的话,那当然就是这样的问题!”当然,问题在于,如果Joe HAD之前想到了这一点,那没有什么帮助:在细节中挣扎的那一周是形成Joe的卷饼直觉的必要和不可或缺的部分,而不是他迟迟未能实现这个想法的悲惨后果。
但是现在Joe写了一篇名为“Monads是Burritos”的monad教程,这个教程是出于善意但错误的假设,如果其他人阅读了他的神奇洞察力,那么了解monads将会很快。 “单子很容易,”乔写道。 “把它们想象成卷饼。”Joe隐藏了关于类型等的所有实际细节,因为这些都是可怕的,如果人们能避免所有困难和令人困惑的东西,人们会学得更好。 当然,事实恰恰相反,乔所做的一切是让人们更难了解单子,因为现在他们不得不花一个星期的时间认为单子是卷饼,变得非常困惑,然后一周试图忘记关于卷饼比喻,然后才能真正开始学习monads。
正如我在很久以前的另一个回答中所说的,sigfpe的文章“你可能发明了单子! (也许你已经有了。),以及Philip Wadler的Monads函数式编程原始文档,都是非常好的介绍(它不是类比,而是大量的例子),但除此之外,你只是继续编码,最终看起来似乎不重要的。
[不是一个真正的答案:一个地方monad存在于所有编程之外,当然是数学。 正如这个热闹的帖子所指出的那样,“一个monad是内部管理员范畴的幺半群,有什么问题?” :-)]
编辑 :提问者似乎已经把这个答案解释为居高临下,并说“Monad太复杂了,他们无法比喻”。 事实上,这种东西并没有打算这样做,而且它往往呈现居高临下的monad-analogies。 也许我应该重申我的观点:“ 你不必理解单子 ”。 您使用特殊的monads是因为它们很有用 - 当您需要Maybe类型时,可以使用Maybe monad,当需要执行IO时使用IO monad,与其他示例类似,显然在C#中使用Nullable <>模式, LINQ和查询解析等等。现在,我们称之为monad的所有这些结构的基础抽象概念是不需要理解或使用特定单子的。 在你看到不止一个例子并且认识到一种模式之后,它可以作为事后的想法:学习从具体到抽象的收益。 直接解释抽象,通过吸引抽象本身的类比,通常不会帮助学习者掌握它的抽象。
在非编程方面:
如果F和G是一对伴随函数,并且F与G相伴,那么组合GF是一个单子。
链接地址: http://www.djcxy.com/p/8361.html上一篇: Monad in non
下一篇: Monad in plain English? (For the OOP programmer with no FP background)