haskell - bind和join是什么关系?
问题描述
我得到的印象是(>>=)
(由 Haskell 使用)和join
(由数学家首选)是“相等的”,因为可以根据另一个来写一个:
import Control.Monad (join)
join x = x >>= id
x >>= f = join (fmap f x)
此外,每个 monad 都是一个仿函数,因为bind
可以用来替换fmap
:
fmap f x = x >>= (return . f)
我有以下问题:
是否有(非递归的)
fmap
定义join
?(fmap f x = join $ fmap (return . f) x
遵循上面的等式,但是是递归的。)“每个单子都是函子”是使用时的结论
bind
(在单子的定义中),但使用时的假设join
?bind
比 更“强大”吗join
?“更强大”是什么意思?
解决方案
monad 可以定义为:
return :: a -> m a
bind :: m a -> (a -> m b) -> m b
或者在以下方面:
return :: a -> m a
fmap :: (a -> b) -> m a -> m b
join :: m (m a) -> m a
对于您的问题:
- 不,我们不能根据 来定义
fmap
,join
否则我们可以fmap
从上面的第二个列表中删除。 - 不,“每个 monad 都是函子”是关于一般 monad 的陈述,无论您是用and
bind
还是用 来定义特定的 monad 。如果您看到第二个定义,则更容易理解该语句,但仅此而已。join
fmap
- 是的,
bind
比join
.join
如果您的意思是“强大”,它具有定义 monad 的能力(总是与fmap
结合),它与“强大”完全一样return
。
对于直觉,请参见例如此答案-bind
允许您将策略/计划/计算(在上下文中)组合或链接在一起。例如,让我们使用Maybe
上下文(或Maybe
monad):
λ: let plusOne x = Just (x + 1)
λ: Just 3 >>= plusOne
Just 4
fmap
还可以让您将上下文中的计算链接在一起,但代价是每一步都会增加嵌套。 [1]
λ: fmap plusOne (Just 3)
Just (Just 4)
这就是为什么您需要join
:将两层嵌套压缩为一层。记住:
join :: m (m a) -> m a
只有挤压步骤不会让你走得很远。您还fmap
需要有一个 monad – and return
,这Just
在上面的示例中。
[1]:不要以相同的顺序接受他们的两个论点fmap
,(>>=)
但不要让你感到困惑。
推荐阅读
- javascript - 在使用 Jest 进行测试之前等待 React 组件状态更新
- python-3.x - 使用 Python 包连接到 Google Cloud 上的 Windows 虚拟机
- c# - SQL Server 和 Visual Studio:如何应对不同的 Microsoft.SqlServer.Types 版本
- java - 公开单个 REST 端点 (GET),它返回一个父对象和与之关联的所有子对象
- c++ - OpenSSL 偶尔会打印随机垃圾
- java - 给定n个包含整数的链表,找到它们之间的共同元素并返回列表
- python - 删除python列表中的重复元素
- objective-c - 在 NSURLSession 完成处理程序中执行 WKWebview 加载请求
- html - 如何在两个引导按钮之间留出空间
- sqlite - 参考数据更改列表视图中的按钮