在Haskell中,monad是根据函数return和bind定义的,其中return有类型a -> m a
,bind有类型m a -> (a -> m b) -> m b
.之前已经指出monad也可以用return和join来定义,其中join是一个带有类型的函数m (m a) -> m a
.绑定可以用连接来定义,但是反过来可能吗?可以在绑定方面加入定义吗?
没有加入,我不知道如果我以某种方式获得"两次包裹"的monadic值,我会做什么,m (m a)
- 没有任何仿函数或monad操作"删除任何层",可以这么说.如果这是不可能的,为什么Haskell和许多其他monad实现在绑定方面定义它们?它似乎没有基于连接的定义有用.
有可能的:
join :: Monad m => m (m a) -> m a join m = (m >>= id)
请注意棘手的实例化>>=
:
(>>=) :: m b -> (b -> m c) -> m c -- choosing b ~ m a , c ~ a (>>=) :: m (m a) -> (m a -> m a) -> m a
所以我们可以正确选择id
第二个参数.
是的,这很简单:
join m = m >>= id