Monad连接功能 [英] Monad join function
问题描述
(>>> =)
所有 Functor
基于的类型类使用某种类型描述额外的结构。有了 Functor
这个额外的结构通常被认为是一个容器,而 Monad
它往往被认为是作为副作用,但这些只是(偶尔具有误导性)短手 - 两种方式都是一样的,并且没有什么特别的 [0] 。
Monad 与其他 使用一个简单的 Functor
s的区别在于它可以将控制流嵌入到额外的结构中。可以这样做的原因是,与在整个结构中应用单个扁平函数的 fmap
不同,(>> =) code>检查单个元素并从中创建新的结构。
Functor
,从每一个原始结构构建新的结构将会嵌套 Functor
,每个图层代表一个控制流点。这显然限制了效用,因为结果是混乱的,并且具有反映所使用的流量控制结构的类型。单边副作用是具有几个其他属性 [1] :
加入
函数不过是该分组操作:嵌套monad类型,如 m(ma)
描述了两种副作用和它们发生的顺序, join
将它们组合在一起形成一个副作用。
因此,就一元副作用而言,绑定操作是一种与相关边效应相关的价值的简写ects和引入新副作用的函数,然后将该函数应用于该值,同时为每个副作用组合。 strong>除 IO
外。 IO
非常特殊。
[1]:如果您将这些属性与 Monoid
实例的规则进行比较,您会发现两者之间有很多相似之处 - 这不是巧合,而是事实只是一名内控官员中的幺半群,有什么问题?线是指。
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?
Actually, in a way, join
is where all the magic really happens--(>>=)
is used mostly for convenience.
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].
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.
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 "side effects" are structures that have a few additional properties[1]:
- Two side effects can be grouped into one (e.g., "do X" and "do Y" become "do X, then Y"), and the order of grouping doesn't matter so long as the order of the effects is maintained.
- A "do nothing" side effect exists (e.g., "do X" and "do nothing" grouped is the same as just "do X")
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.
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]: Except IO
. IO
is very special.
[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屋!