Monad 通常按 return
和 bind
的顺序进行解释。但是,我认为您也可以根据 join
实现 bind
(和 fmap
?)
在缺乏一流函数的编程语言中,bind
使用起来极其尴尬。另一方面,join
看起来相当简单。
但是,我并不完全确定我理解 join
的工作原理。显然,它具有[Haskell]类型
join :: Monad m => m (m x) -> m x
对于列表 monad,这是简单且明显的concat
。但对于一般的 monad,从操作上来说,这个方法实际上做了什么?我了解它对类型签名的作用,但我正在尝试弄清楚如何在 Java 或类似语言中编写类似的内容。
(实际上,这很简单:我不会。因为泛型已损坏。;-)但原则上问题仍然存在......)
<小时/>哎呀。看起来以前已经问过这个问题:
有人可以使用 return
、fmap
和 join
勾勒出常见 monad 的一些实现吗? (即,根本不提及 >>=
。)我认为这可能有助于它深入到我愚蠢的大脑中......
最佳答案
在不深入隐喻的情况下,我是否可以建议将典型的单子(monad) m
解读为“生成 a 的策略”,因此类型 m 值
是一流的“创造值(value)的策略”。不同的计算或外部交互概念需要不同类型的策略,但一般概念需要一些规则的结构才能有意义:
- 如果您已经有一个值,那么您就有一个策略来生成一个值 (
return::v -> m v
),该值除了生成您拥有的值之外什么也不包含; - 如果您有一个将一种值转换为另一种值的函数,您只需等待即可将其提升为策略 (
fmap::(v -> u) -> m v -> m u
)让战略实现其值(value),然后对其进行转型; - 如果您有一个策略来生成一个策略来生成一个值,那么您可以构造一个策略来生成一个值 (
join::m (m v) -> m v
),该策略遵循外部策略,直到它产生内部策略,然后遵循该内部策略一直到一个值。
让我们举个例子:叶子标记的二叉树...
data Tree v = Leaf v | Node (Tree v) (Tree v)
...代表通过抛硬币来生产东西的策略。如果策略是Leaf v
,那就是你的v
;如果策略是Node h t
,则抛一枚硬币,如果硬币显示“正面”,则继续策略h
;如果硬币显示“反面”,则继续策略t
”。
instance Monad Tree where
return = Leaf
生成策略的策略是一棵带有树标记叶子的树:我们可以将每个这样的叶子移植到标记它的树中......
join (Leaf tree) = tree
join (Node h t) = Node (join h) (join t)
...当然我们有 fmap
它只是重新标记叶子。
instance Functor Tree where
fmap f (Leaf x) = Leaf (f x)
fmap f (Node h t) = Node (fmap f h) (fmap f t)
这是一个生成 Int
的策略。
抛一枚硬币:如果是“正面”,则再抛一枚硬币以在两种策略之间做出决定(分别产生“抛硬币产生 0 或产生 1”或“产生 2”);如果是“反面”,则产生第三个(“抛硬币产生 3 或抛硬币产生 4 或 5”)。
很明显,join
是为了制定一个生成Int
的策略。
我们利用的是这样一个事实:“产生值(value)的策略”本身就可以被视为一种值(value)。在 Haskell 中,策略作为值的嵌入是沉默的,但在英语中,我使用引号来区分使用策略和仅仅谈论它。 join
运算符表达了“以某种方式产生然后遵循策略”的策略,或者“如果您被告知一个策略,那么您可以使用它” ”。
(元。我不确定这种“策略”方法是否是思考单子(monad)和值/计算区别的通用方法,或者它是否只是另一个糟糕的隐喻。我确实发现叶子标记的树状结构类型是直觉的有用来源,这也许并不奇怪,因为它们是免费单子(monad),具有足够的结构作为单子(monad),但仅此而已。)
PS“绑定(bind)”的类型
(>>=) :: m v -> (v -> m w) -> m w
表示“如果您有一个生成 v
的策略,并且对于每个 v 有一个生成 w
的后续策略,那么您就有一个生成w
”。我们如何通过 join
来捕捉这一点?
mv >>= v2mw = join (fmap v2mw mv)
我们可以通过 v2mw
重新标记我们的 v
生成策略,生成 w
而不是每个 v
值- 制定随之而来的策略 - 准备加入
!
关于haskell - 使用 Join() 而不是 Bind() 的 Monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11234632/