根据分类术语,FP中的monad是什么?

Ker*_* SB 49 monads haskell functional-programming category-theory

每当有人承诺"解释monad"时,我的兴趣就会被激怒,只有当被指称的"解释"是一长串的例子时才会被沮丧所取代,这些例子是由一些副手的评论所终止的,即"数学理论"背后的"深奥"在这一点上,"是"太复杂而无法解释".

现在我要求相反的事情.我对类别理论有着扎实的把握,我并不害怕图表追逐,Yoneda的引理或衍生的函子(实际上是在分类意义上的monad和adjunction).

有人能给我一个清晰简洁的定义monad在函数式编程中的含义吗?越少越好的例子:有时一个清晰的概念说明了一百多个胆小的例子.尽管我不挑剔,但Haskell作为演示语言会做得很好.

scl*_*clv 31

这个问题有一些很好的答案:Monads作为附属物

更重要的是,德里克·埃尔金斯在TMR#13中的"使用类别理论计算单子"文章应该具有您正在寻找的那种结构:http://www.haskell.org/wikiupload/8/85/TMR- Issue13.pdf

最后,也许这真的是最接近你正在寻找的东西,你可以直接找到源头,看看Moggi关于这个主题的开创性论文,从1988-91:http://www.disi.unige.it/人/ MoggiE/publications.html

特别参见"计算和monad的概念".


我自己肯定太精简/不精确:

从一个类别开始,该类别Hask的对象是Haskell类型,其状态是函数.功能也是产品中的对象Hask.Hask笛卡尔也是如此.现在介绍一个箭头,将每个对象映射HaskMHask其中的对象的子集Hask.单元!接下来介绍一个箭头,将每个箭头映射Hask到箭头上MHask.这为我们提供了地图,并制作MHask了一个协变的endofunctor.现在介绍一个箭头,映射MHaskMHask(通过单位)中的对象MHask生成的每个对象到生成它的对象.加入!从那里,MHask是一个monad(和一个monoidal endofunctor更精确).

我确信有上述原因不足的原因,这就是为什么我真的会指导你,如果你正在寻找形式主义,尤其是Moggi论文.


Dan*_*ton 17

作为对Carl的答案的赞美,Haskell中的Monad(理论上)是这样的:

class Monad m where
  join :: m (m a) -> m a
  return :: a -> m a
  fmap :: (a -> b) -> m a -> m b
Run Code Online (Sandbox Code Playgroud)

请注意,"bind"(>>=)可以定义为

x >>= f = join (fmap f x)
Run Code Online (Sandbox Code Playgroud)

根据Haskell Wiki

在类别A单子Ç是一个三元组(˚F:C→C,η:标识˚F,μ:˚F˚F˚F)

......有一些公理.对于Haskell中,fmap,return,和join排队与˚F分别,η和μ.(fmap在Haskell中定义了一个Functor).如果我没有记错,斯卡拉调用这些map,purejoin分别.(Scala调用bind"flatMap")

  • 我喜欢这个答案,因为尽管monads对于我们作为程序员有用*主要是因为`>> =`,但是(`fmap`,`join`,`return`)三元组更能说明monad实际上*是*(imo) .当我终于明白了什么["monad只是endofunctors类别中的monoid"]时(http://stackoverflow.com/questions/3870088/a-monad-is-just-a-monoid-in-the-category -of-endofunctors -whats-the-problem)实际上*意味着*,我开悟了. (8认同)

Car*_*arl 12

好的,使用Haskell术语和例子......

函数式编程中的monad是具有类型的数据类型的组合模式* -> *.

class Monad (m :: * -> *) where
    return :: a -> m a
    (>>=)  :: m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

(这个类比Haskell中的更多,但那些是重要的部分.)

如果数据类型可以在实现中满足三个条件的同时实现该接口,则该数据类型是monad.这些是"monad法则",我将把它留给那些冗长的解释,以获得完整的解释.我将这些定律概括为" (>>= return)是一种身份功能,并且(>>=)是联想的".它真的不止于此,即使它可以更精确地表达.

而这所有的单子是.如果您可以在保留这些行为属性的同时实现该接口,那么您就拥有了一个monad.

这个解释可能比你想象的要短.那是因为monad界面真的非常抽象.令人难以置信的抽象层次是为什么许多不同的东西可以被建模为monad的一部分.

不那么明显的是,与接口一样抽象,它允许对任何控制流模式进行一般建模,而不管实际的monad实现.这就是为什么Control.Monad包GHC的base图书馆有像组合程序when,forever等等.这就是为什么有能力明确的抽象超过任何单子的实现是强大的,特别是从类型系统的支持.

  • @sclv:不,`fmap`也可以用`>> =`和`return`来定义:`fmap fm = m >> = return.F`. (4认同)

npo*_*cop 6

你应该阅读Eugenio Moggi撰写的论文"计算和单子的概念",它解释了当时提出的monad在构造有效语言的指称语义方面的作用.

还有一个相关的问题:

学习Haskell等纯函数式语言背后的理论的参考资料?

因为你不想挥手,你必须阅读科学论文,而不是论坛答案或教程.


Tik*_*vis 5

我真的不知道我在说什么,但这是我的看法:

Monads用于表示计算.您可以将正常的过程程序(基本上是一个语句列表)视为一堆组合计算.Monads是这个概念的概括,允许您定义语句的组合方式.每个计算都有一个值(它可能只是()); monad只是决定了一系列计算中的值如何表现.

注释实际上是说明这一点:它基本上是一种特殊的基于语句的语言,它允许您定义语句之间发生的事情.就好像你可以定义";" 使用类C语言.

从这个角度来看,到目前为止我使用过的所有monad都是有意义的:State不会影响值,但会更新第二个值,该值在后台从计算传递到计算; Maybe如果它遇到过一个短路值Nothing; List让你传递可变数量的值; IO让您以安全的方式传递不纯的价值.我使用过的更专业的monad Gen和Parsec解析器也很相似.

希望这是一个明确的解释,并非完全偏离基础.


hug*_*omg 5

monad是endofunctors类别中的monoid,问题是什么?.

抛开幽默,我个人认为monads,因为它们在Haskell和函数式编程中使用,从monads-as-an-interface的角度(如Carl和Dan的答案)更好地理解,而不是monads-as-从类别理论的角度来看.我必须承认,当我不得不在真实项目中使用来自另一种语言的monadic 时,我才真正内化了整个monad事物.

你提到你不喜欢所有的"很多例子"教程.有没有人向你指出尴尬的小队纸?它专注于IO monad,但介绍给出了一个很好的技术和历史解释,说明为什么 monad概念首先被Haskell所接受.