Monad 连接函数 [英] Monad join function
问题描述
虽然 monad 在 Haskell 中使用 bind 和 return 函数表示,但它们也可以使用 join 函数进行另一种表示,例如 在此讨论.我知道这个函数的类型是 M(M(X))->M(X),但这实际上是做什么的?
While monads are represented in Haskell using the bind and return functions, they can also have another representation using the join function, such as discussed here. I know the type of this function is M(M(X))->M(X), but what does this actually do?
推荐答案
实际上,在某种程度上,join
才是真正发生奇迹的地方--(>>=)
主要是为了方便.
Actually, in a way, join
is where all the magic really happens--(>>=)
is used mostly for convenience.
所有基于 Functor
的类型类使用某种类型描述附加结构.对于 Functor
,这个额外的结构通常被认为是一个容器",而对于 Monad
,它往往被认为是副作用",但这些只是(偶尔误导)速记——无论哪种方式都是一样的,并没有什么特别的[0].
All Functor
-based type classes describe additional structure using some type. With Functor
this extra structure is often thought of as a "container", while with Monad
it tends to be thought of as "side effects", but those are just (occasionally misleading) shorthands--it's the same thing either way and not really anything special[0].
Monad
与其他 Functor
相比的显着特点是它可以将控制流嵌入到额外的结构中.它可以这样做的原因是,与 fmap
在整个结构上应用单个平面函数不同,(>>=)
检查单个元素并构建 新结构.
The distinctive feature of Monad
compared to other Functor
s is that it can embed control flow into the extra structure. The reason it can do this is that, unlike fmap
which applies a single flat function over the entire structure, (>>=)
inspects individual elements and builds new structure from that.
使用普通的Functor
,从原始结构的每一部分构建新结构将嵌套Functor
,每一层代表一个控制流点.这显然限制了实用性,因为结果是混乱的并且具有反映所使用的流控制结构的类型.
With a plain Functor
, building new structure from each piece of the original structure would instead nest the Functor
, with each layer representing a point of control flow. This obviously limits the utility, as the result is messy and has a type that reflects the structure of flow control used.
Monadic副作用"是具有一些附加属性的结构[1]:
Monadic "side effects" are structures that have a few additional properties[1]:
- 两个副作用可以归为一个(例如,做 X"和做 Y"变成做 X,然后 Y"),分组的顺序并不重要,只要效果的顺序维护.
- 存在什么都不做"的副作用(例如,做 X"和什么都不做"分组与仅做 X"相同)
join
函数只不过是分组操作:像 m (ma)
这样的嵌套 monad 类型描述了两个副作用及其出现的顺序,并且 join
将它们组合成一个副作用.
The join
function is nothing more than that grouping operation: A nested monad type like m (m a)
describes two side effects and the order they occur in, and join
groups them together into a single side effect.
因此,就monadic副作用而言,绑定操作是取一个带有相关副作用的值和一个引入新副作用的函数,然后在组合副作用的同时将该函数应用于该值"的简写每个".
So, as far as monadic side effects are concerned, the bind operation is a shorthand for "take a value with associated side effects and a function that introduces new side effects, then apply the function to the value while combining the side effects for each".
[0]:除了IO
.IO
非常很特别.
[1]:如果将这些属性与 Monoid
实例的规则进行比较,您会发现两者之间非常相似——这不是巧合,实际上是什么只是一个内函子范畴的幺半群,有什么问题?"行是指.
[1]: If you compare these properties to the rules for an instance of Monoid
you'll see close parallels between the two--this is not a coincidence, and is in fact what that "just a monoid in the category of endofunctors, what's the problem?" line is referring to.
这篇关于Monad 连接函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!