代码之家  ›  专栏  ›  技术社区  ›  fig

非编程术语中的单子[duplicate]

  •  27
  • fig  · 技术社区  · 14 年前


    What is a monad?

    10 回复  |  直到 7 年前
        1
  •  28
  •   Owen S.    14 年前

    以下是我目前的尝试:

    桶队模型 :

    1. 每次操作都是一个人排队;i、 有一个明确的操作顺序发生。
    2. >>= ,操作)。
    3. return 操作就是把东西放进桶里的操作。
    4. >> )操作时,桶里的东西在传递给下一个人之前就被倾倒了。下一个人不在乎桶里装的是什么,他们只是等着收到。
    5. 在单子的情况下 () ,一张罚单正在桶里传来传去。它叫做“单位”,只是一张白纸。
    6. 在伊奥·蒙纳德的例子中,每个人都大声说出一些非常深刻或非常愚蠢的话,但他们只能在拿着水桶的时候说话。


    我很感谢你的支持,但遗憾的是,单子教程诅咒再次袭来。我所描述的只是带有容器的函数应用程序,而不是monad!但我不是虚无主义者我相信单子的诅咒可以被打破!所以这里有一个更,呃, 复杂的 我认为这幅画描述得更好一点。你决定是否值得带去见你的朋友。

    与项目经理合作 . 项目经理们站在除了第一个队员以外的所有人后面。水桶大队的队员们坐在凳子上,面前摆着水桶。

    第一个人收到一些东西,用它做一些事情,然后把它放进桶里。然后那个人把手拿开,不要交给旅里的下一个人,那太容易了!:-)而是站在那个人后面的项目经理。

    绑定 ,或 >>= fail ). 她可能会决定绕过前面的人,把桶递给旅里的下一个经理,而不必再费吹灰之力(这就是我们的情况) Nothing Maybe >> )她只是轻拍面前那个人的肩膀,而不是递给他们任何东西。

    当下一个人做了一桶东西,这个人把它交给下一个项目经理。下一个项目经理再次弄清楚如何处理她给的桶,然后把桶里的东西交给她自己。最后,铲斗通过 后面 在项目经理的链条上,他们可以选择使用bucket(比如 List 单子集合所有结果)。第一个项目经理产生了一桶东西作为结果。

    在这种情况下 do 语法上,每个人实际上都是一个操作,它是在过去的所有事情的上下文中当场定义的,就好像项目经理传递的不仅仅是桶中的东西,还有以前团队成员生成的值(呃,stuff)。如果使用bind和sequence而不是使用 语法注意:每个连续的“语句”都是在该点之前的操作中构造的匿名函数。

    返回 操作如上所述。

    “但这太复杂了!为什么人们不能自己把桶卸下来呢。好吧,项目经理可以在幕后做一堆工作,否则会使人的工作复杂化。我们正试图让这些旅的成员轻松些,这样他们就不用做太多了。例如,在Maybe monad的例子中,每个人不必检查他们得到的东西的价值,看看他们是否得到了什么,项目经理会为他们处理这些。

    . 不过,有时你希望一个人有更复杂的事情要做,他们希望对生产的桶有一些控制(例如,他们是否需要返回) 没有什么 在这种情况下 也许 吧

    要点是:

    1. 操作是按顺序进行的。
    2. 每个人都知道如何做桶,但不知道如何从桶里取出东西。
    3. 每个项目经理都知道如何处理桶,以及如何从桶中取出东西,但并不关心桶中有什么。

    我的睡前指导到此结束-P

        2
  •  40
  •   Community Mr_and_Mrs_D    4 年前

    Abstraction, intuition, and the “monad tutorial fallacy”

    乔·哈斯凯勒正在努力学习单子。经过一个星期的努力理解,看看例子,写代码,读别人写的东西,他终于有了一个啊哈!瞬间:一切都突然明朗了,乔明白了蒙纳德的意思!当然,真正发生的是,乔的大脑将所有的细节整合到了一个更高层次的抽象中,乔可以用这个隐喻来直观地理解单子;让我们假设乔斯的比喻是,单子就像玉米煎饼。乔在这里严重曲解了自己的思维过程:当然!乔想。现在一切都那么简单。理解单子的关键是它们就像煎饼。要是我以前想到这个就好了!当然,问题是,如果乔之前就想到了这一点,那就不会有什么帮助了:一周的细节挣扎是形成乔的玉米饼直觉的必要和不可或缺的一部分,而不是他没能早点想到这个想法的可悲后果。

    但是现在乔去写了一本蒙纳德的教程,名为《蒙纳德是煎饼》,基于一个善意但错误的假设:如果其他人读到他的魔法洞察力,了解蒙纳德对他们来说将是一个瞬间。“单子很容易,”乔写道。把它们想象成玉米煎饼。乔隐藏了所有关于类型等的实际细节,因为这些都很可怕,如果人们能够避免那些困难和混乱的东西,他们会学到更好的东西。当然,事实恰恰相反,乔所做的只是让人们更难了解单子,因为现在他们不得不花一个星期的时间认为单子是玉米煎饼,变得完全困惑,然后一个星期试图忘记玉米煎饼的比喻,在他们真正开始学习单子之前。

    就像我在书中说的 another answer 很久以前,sigfpe的文章 You Could Have Invented Monads! (And Maybe You Already Have.) Monads for functional programming ,都是很好的介绍(它提供的不是类比而是大量的例子),但除此之外,您只需继续编写代码,最终一切都会显得微不足道。

    [这不是一个真正的答案:单子存在于所有编程之外的一个地方,当然是数学。作为 this hilarious post 指出,“单子是内函子范畴中的幺半群,有什么问题?”:—)]


    编辑 often appear condescending . 也许我应该重申我的观点 other examples ,和 apparently in C#

        3
  •  15
  •   Mau    14 年前

    非编程术语:

    如果 F 是一对伴随函子,具有 左伴随 ,然后是构图 G.F.公司 是单子。

        4
  •  12
  •   RD1    14 年前

    编程之外有什么概念/东西吗 编程,而不仅仅是FP),它可以说是在 有意义的方式?

    是的,事实上有。单子与模态逻辑中的“可能性”有着非常直接的联系,它是Curry-Howard同构的推广(请参见: A Judgmental Reconstruction of Modal Logic. )

    其基本思想是,没有单子,所有的表达式都存在于同一个世界,所有的计算都在这个世界上进行。但是对于单子,可以有许多世界,计算在它们之间移动(e、 例如,每个世界可能指定某个可变状态的当前值)

    在这个视图中,单子 p 意思是“在当前世界可能到达的世界中”。

    特别是如果 t

    x :: t 意味着t型的东西在现在的世界上是直接可用的
    y :: p t 意味着t型的东西在一个可以从当前世界到达的世界中是可用的

    那么, return 让我们把现在的世界当作一个可以到达的世界。

    return :: t -> p t

    以及 >>=

    (>>=) :: p t -> (t -> p s) -> p s

    所以呢 >> 可以用来构造一条从较小的路径到其他世界的可到达世界的路径。

    世界就像是州,这很容易解释。对于类似IO monad的东西,这也很简单:一个程序与外部世界的所有交互都指定了一个世界。

    对于无终止的两个世界就足够了——一个普通的世界,一个无限遥远的未来(应用>>=第二个世界是允许的,但是你不太可能观察到在那个世界中发生了什么。)对于延续单元组,当延续被正常使用时,世界保持不变,当它们不被正常使用时,还有额外的世界(例如,对于callcc)。

        5
  •  6
  •   missingfaktor Kevin Wright    14 年前

    this excellent post 作者:Mike Vanier,

    Haskell的关键概念之一 编程语言就是这个概念 难学(我也学过), 结果是 就像杰夫写的《单子》一样 纽伯恩)。甚至有人说 写单子教程是一种宗教仪式 新Haskell程序员的文章。 然而,一个很大的问题是 monad教程 解释参考文献中的单子 现有的概念 GHC编译器和通用Haskell grand 我来告诉你原因。

    当你试图解释的时候,这是很自然的 已经知道了。这很管用 当新事物在某些方面相似时 当新事物完全过时 一个人的经历 学习它。例如,如果你是 试图解释火对人来说是什么 从未见过火的穴居人, 你会说什么?”有点像 空气和水的交叉,但是 热……“不是很有效。同样地, 解释原子是什么 因为我们知道电子 真正地 环绕地球运行 原子核就像围绕恒星的行星, 以及“非本地化”的概念 “电子云”其实并不意味着 从直觉的角度来看,这是真的。 力学很好理解;我们只是 对什么没有很好的直觉 数学真的意味着。

    这和单子有什么关系?时间 同样,在教程、博客文章中 在Haskell的邮件列表上 你见过单子的解释吗 据推测,直觉的方式:单子是 “有点像行动”或“有点 就像一个容器。什么东西 既是行动又是容器? 这些不是独立的概念吗?是一个 莫纳德有些奇怪的“活跃” 声称单子是一种 不正确。那么什么是单子呢?

    答案如下: 纯粹抽象的概念,没有 你可能听说过 以前。 从范畴理论,这是 范畴论就是把所有的概念抽象出来 揭露相似之处和相似之处 在看似不同的区域之间(例如 例如,在代数和 数学的基础 概念,从而减少冗余。 )这件事我可以讲上好一阵子 我想说的是。)因为我 猜想大多数程序员 学习Haskell对 对他们来说意味着什么。那不是 意味着他们需要了解 范畴论中单子的应用 哈斯凯尔(幸运的是),但确实如此 意味着他们需要舒服一点 抽象的方式 用于。

    请转到文章顶部的链接阅读全文。

        6
  •  5
  •   intoverflow    14 年前

    在实践中,我接触过的大多数单子的行为都像某种隐含的上下文。

    就像你和一个朋友在谈论一个共同的朋友。每次你说“鲍勃”,你们都是指同一个鲍勃,这一事实只是在你的谈话中含蓄地穿插,因为鲍勃是你共同的朋友。

    当然,你可以和你的老板(不是你的朋友)谈谈你的跳级经理(不是你的朋友),他碰巧叫鲍勃。在这里你可以有另一个对话,同样有一些隐含的含义,只有在对话的上下文中才有意义。你甚至可以说出和你朋友说的完全一样的话,但是因为不同的语境,它们会有不同的含义。

    在编程上也是一样的。就这样 tell 行为取决于你在哪个单子里;信息的组合方式( >>=

    见鬼,连谈话的规则都是一元的。”不要告诉任何人我告诉你的事“以同样的方式隐藏信息” runST 防止引用从 ST

    希望有帮助。

        7
  •  3
  •   C. A. McCann Ravikant Cherukuri    14 年前

    a nicely detailed description of monads

    YouTube上也有一系列视频解释了这种单子的种类——以下是 the first in the sequence .

        8
  •  2
  •   J Cooper    14 年前

    我喜欢把它们看作是可以“绑定”的计算的抽象。或者,玉米饼!

        9
  •  2
  •   Paul Johnson    14 年前

    这取决于你在和谁说话。任何解释都必须放在正确的层次上。我对化学工程师的解释和对数学家或财务经理的解释是不同的。

    最好的方法是把它和你谈话的人的专业知识联系起来。作为一个规则排序是一个相当普遍的问题,所以试着找到一些人知道你说“先做X,然后做Y”。然后解释普通编程语言是如何遇到这个问题的;如果你对一台计算机说“做X,然后做Y”,它会立即做X和Y而不等待进一步的输入,但不能同时为其他人做Z;计算机的“然后做”的概念和你的不同。因此程序员必须以不同于你(专家)解释的方式来编写他们的程序。这在你说的话和程序说的话之间造成了差距。跨越这一鸿沟需要时间和金钱。

        10
  •  1
  •   HaskellElephant jeni    14 年前

    是的,Monads来自haskell之外的概念。哈斯克尔有许多术语和思想是从范畴理论中借用来的。这是其中之一。如果这个不是程序员的人是研究范畴论的数学家,就说:“单子是内函子范畴中的幺半群。”