在非编程术语中的Monad
在非编程术语中:
如果F和G是一对伴随函子,其中F是G的左伴随,则复合G.F是一个单子。
你刚才是不是从维基百科上复制了这句话?实际上,函数式编程单子显然对应于数学中的强单子。
这并没有帮助,你刚刚从编程术语转移到了(可能是)数学术语...
RCIX:你想要什么术语?单子是一个数学概念。
这并没有真正帮助 - 几乎每个知道一对伴随函子是什么的人都知道单子是什么。而且,如前所述,在这个上下文中需要解释的是强单子。
那么,函子与编程有什么关系呢?我是不是应该思考程序(一组指令)执行的操作,还是执行的文件的文本?
我对函子的理解是它将(点和箭头)
映射到(点和箭头)
。我听说在函数式编程中,你说这个是那个,而不是像过程式编程那样说“计算机,先做这个再做那个”。你能帮我完善这个联系吗?
Monad in non-programming terms是一个解释Monad的概念的比喻。文章中提到,Monad可以被比喻为一个“桶传递队”,每个操作都是一个排队的人,操作的顺序是明确的。每个人从一个桶中取出东西,然后放入新的东西,然后将桶传递给下一个人。return操作是将东西放入桶中。在sequence操作中,桶的内容在传递给下一个人之前被清空。在IO monad中,每个人只有在拿着桶的时候才能说话。文章还提到了其他Monad的比喻,如State monad和Cont monad。
这个比喻的出现是为了更好地解释Monad的概念。通过比喻为一个桶传递队,可以更容易地理解Monad中操作的顺序和桶的传递过程。每个人只知道如何制作桶,但不知道如何从桶中取出东西。每个项目经理知道如何处理桶,但不关心桶里的内容。这个比喻可以帮助初学者更好地理解Monad的核心概念,特别是bind和sequence操作。
通过这个比喻,可以更轻松地描述State monad的get和put操作。get操作可以比喻为一个人将状态复制一份并传递给下一个人,put操作可以比喻为一个人将状态替换为接收到的值并传递一个空白的纸张。其他人只关注他们手中接收到的东西,而不关心状态。
总之,这个比喻可以帮助初学者更好地理解Monad的概念,特别是bind和sequence操作。虽然这个比喻可能对一些特定的Monad并不适用,但它可以帮助初学者建立对Monad的基本理解。
在非编程领域,有几件事情可以说与monad类似。然而,这些都不能帮助你理解monad。请阅读“Abstraction, intuition, and the 'monad tutorial fallacy'”:
Joe Haskeller试图学习monad。在努力一个星期后,他通过查看例子、编写代码、阅读他人的文章,最终有了一个“啊哈!”的时刻:一切突然变得清晰,Joe理解了monad!当然,真正发生的是Joe的大脑将所有的细节整合到了一个更高层次的抽象中,一个Joe可以用来直观理解monad的隐喻。假设Joe的隐喻是monad就像burrito(墨西哥卷饼)。这里Joe严重误解了自己的思维过程:“当然!”Joe想。“现在一切都这么简单了。理解monad的关键在于它们就像burrito一样。要是我早点想到就好了!”当然,问题是,如果Joe早点想到了,也不会有帮助:通过一周的细节挣扎是形成Joe的Burrito直觉的必要和重要部分,而不是他未能早点想到这个想法的悲惨后果。
然而,现在Joe写了一个名为“Monads are Burritos”的monad教程,他以善意但错误的假设为基础,即如果其他人阅读他的神奇洞察力,学习monad对他们来说将是一件轻而易举的事情。“Monads很简单,”Joe写道。“把它们想象成burritos。”Joe隐藏了所有关于类型等实际细节,因为那些令人害怕,而且人们如果能避免所有那些困难和混乱的东西,他们会更好地学习。当然,事实恰恰相反,Joe所做的只是让人们更难学习monad,因为现在他们必须花一周时间认为monad就像burrito,然后一周时间试图忘记对burrito的类比,然后才能真正开始学习monad的业务。
正如我在很久以前的另一个回答中所说的那样,sigfpe的文章“You Could Have Invented Monads!(And Maybe You Already Have.)”以及Philip Wadler的原始论文“Monads for functional programming”都是很好的入门资料(它们提供了许多例子而不是类比),但除此之外,你只需要不断编码,最终一切都会变得微不足道。
[非真正的回答:当然,monad在所有编程之外的数学中也存在。正如这篇有趣的帖子所指出的那样,“monad是函子范畴中的幺半群,有什么问题?”]
编辑:提问者似乎将这个答案解释为傲慢,认为“monads非常复杂,超越了类比的范畴”。实际上,我并没有这样的意图,而且通常是类比monads的方式显得傲慢。也许我应该重新表述我的观点:“你不需要理解monads”。你使用特定的monads是因为它们有用-当你需要Maybe类型时,你使用Maybe monad,当你需要进行IO时,你使用IO monad,类似地,其他例子,以及显然在C#中,你使用Nullable<>模式、LINQ和查询语法等。现在,对于这些结构背后存在一个单一的通用抽象,我们称之为monad的认识,并不是理解或使用特定monads所必需的。这是一种事后的想法,当你看到多个例子并识别出一个模式时,学习从具体到抽象。直接通过引用抽象本身的类比来解释抽象通常不会帮助学习者理解它是什么抽象的。
这是一个不幸的情况。我想知道这个人是否找到了他所要求的monad教程?
+1. Mike Vanier也提出了相同的观点。
“糟糕”吗?不是的。任何抽象概念都可以通过查看各种特例(示例)并进行概括来学习,但很少通过类比(通常是不完美的,最多只能让它变得不那么可怕,而不能帮助理解)。在你理解了monads是什么之后,你将能够想出许多类比-而且这个练习甚至可能对你有帮助-但没有证据表明任何无数的monad-by-analogy教程能够帮助任何人理解它们的。:-)
(我试图提取最小的量来传达这个观点。)monads没有什么特别的;每个抽象都是如此。monads并不是那么复杂;只需要看一下例子,理解你关心的monads,超越可怕的名字,开始编码,总有一天总体思路就会清晰起来。在monad教程的时间轴中查看一小部分无数monad教程的例子,其中包含各种类比。它们并没有提供太多帮助!
-gnuton:或许Haskeller们从经验中发现,专注于类比“使实际理解变得更困难”。一个非答案正在被投票支持,因为你的问题是错误的。为什么不再次阅读这个答案,因为你可能不会从任何其他地方得到更好的解释,特别是来自“现实世界”的类比。
来自Ralph B. Boas的相关引用,《Can We Make Mathematics Intelligible?》:“假设你想要向一个非常小的孩子教授‘猫’的概念。你会解释猫是一种相对较小、主要是食肉的哺乳动物,有可伸缩的爪子,有独特的声音输出等吗?我敢打赌不会。你可能会向孩子展示许多不同的猫,每次都说‘小猫’,直到它明白为止。更一般地说,通过经验进行抽象是最好的。”
还有一篇有趣的文章在这里:The “What Are Monads?” Fallacy,它认为,甚至询问“什么是monads”都是错误的问题,就像询问“什么是乐器”而不是学会演奏一样。