术语" monad"适用于像Maybe或List这样的类型的值,还是仅适用于类型本身?

时间:2012-06-16 21:57:30

标签: terminology monads

我注意到“monad”这个词似乎以一种不一致的方式使用。我开始相信这是因为很多(如果不是大多数)monad教程是由那些刚刚开始自己​​构建monad的人写的(例如:核废料太空服卷饼),所以这个术语结束了得到了一些过载/损坏。

特别是,我想知道术语“monad”是否可以应用于Maybe,List或IO等类型的单个值,或者术语“monad”是否真的只应用于类型本身。

这是一个微妙的区别,所以也许类比可能会更清楚。在数学中,我们有,环,字段,组等。这些术语适用于整个值集以及可以对它们执行的操作,而不是单个元素。例如,整数(以及加法,否定和乘法的运算)形成一个环。你可以说“整数是一个戒指”,但你永远不会说“5是一个戒指”。

那么,你能说“Just 5是一个单子”,还是会说“5是一个戒指”?我不知道类别理论,但我的印象是说“Maybe是一个单子”而不是“Just 5是一个单子”真的是有意义的。

5 个答案:

答案 0 :(得分:19)

“Monad”(和“Functor”)通常被误用作为描述值。 没有价值是monad,functor,monoid,applicative functor等。 只有类型&类型构造函数(高级类型)可以。 当你听到(并且你会)“列表是幺半群”或“函数是monad”等,或者“这个函数以monad为参数”时,不要相信它。 问一下发言者“考虑到Haskells类对类型(包括高阶类型)而不是值进行分类,任何值都是monoid(或monad或......)怎么样?” 列表不是幺半群(等)。 List a是。

我的猜测是,这种流行的滥用源于具有价值类而非类型类的主流语言,因此习惯性,无意识的价值阶级思维潜入其中。

为什么我们精确地使用语言是否重要? 因为我们用语言思考并且我们建立&通过语言传达理解。 因此,为了有清晰的想法,有助于拥有清晰的语言(或能够随时)。

“我们语言的邋is让我们更容易有愚蠢的想法。重点是这个过程是可逆的。” - George Orwell,Politics and the English Language

编辑:这些评论适用于Haskell,而不是类别理论的更一般设置。

答案 1 :(得分:11)

List是monad,List a是一种类型,[]List a(类型的元素)。

从技术上讲,monad是一个具有额外结构的仿函数;在Haskell中,我们只使用Haskell类型的函子到它自己。

因此特别是一个“函数”,它接受一个类型并返回另一个类型(它有类* -> *)。

ListState sMaybe等是monad。 State不是monad,因为它有* -> * -> *种。

(除了:混淆问题,Monads只是仿函数,如果我给自己一个部分有序的集合A,那么它形成一个类别,如果一个&lt的话,Hom(a,b)= {1 element} ; = b和Hom(a,b)=否则为空。现在任何增加函数f:A - > A形成一个仿函数,monad是那些满足x< = f(x)和f(f(x)的函数))< = f(x),因此f(f(x))= f(x) - 这里的monad在技术上是“A - > A的元素”。另见closure operators。)

(除了2:因为你似乎知道一些数学,我鼓励你阅读类别理论。你会看到代数结构可以看作是由monad引起的。见this excellent blog entry from the excellent blog by Dan Piponi预告片。)

答案 2 :(得分:4)

确切地说,monad是类别理论的结构。他们没有直接的代码对应物。为简单起见,我们来谈谈一般的仿函数而不是monad。在Haskell的情况下,粗略地说,仿函数是从一类类型到一类类型的映射,它们也将第一类中的函数映射到第二类中的函数。 Functor实例允许您访问映射函数,但不直接捕获仿函数的概念。

然而,可以说Functor实例中提到的类型构造函数是实际的函子:

instance Functor Tree

在这种情况下,Tree是仿函数。但是,因为Tree是一个类型构造函数,所以它不能代表同时构成仿函数的两个映射函数。映射函数的函数称为fmap。因此,如果您想要精确,则必须说元组(Tree, fmap)是仿函数,其中fmap是来自fmap Tree的特定Functor实例。为方便起见,我们再次说Tree是仿函数,因为相应的fmap来自其Functor实例。

请注意,仿函数始终是* -> *种类型。因此Maybe Int不是仿函数 - 仿函数是Maybe。人们经常谈论“国家monad”,这也是不精确的。 State是一个由无数个状态monad组成的整个家族,正如你在实例中看到的那样:

instance Monad (State s)

对于每种类型s,类型构造函数State s(种类* -> *)是 a 状态monad,其中之一。

答案 3 :(得分:2)

  

所以,你能说“Just 5是monad”,还是说“5是一个戒指”会不会错误?

你的直觉是完全正确的。 Int Ring(或AbelianGroup或其他)属于Maybe Monad(或Functor或其他)。值(5Just 5等)并不重要。

在代数中,我们说整数集形成一个环;在Haskell中,我们会(非正式地)说IntRing类型类的成员,或者(稍微更正式地)Ring实例存在Int个实例。您可能会发现this proposal有趣和/或有用。无论如何,与monads相同。

  

我不知道类别理论,但是......

无论如何,如果你对抽象代数了解一两件事,那你就是金色的。

答案 4 :(得分:1)

我会说“Just 5是一个Monad实例的类型”,就像我会说“5是一个有类型的数字(整数)是一个环”。

我使用术语实例,因为在Haskell中你是如何声明类型类的实现的,而Monad就是其中之一。