例如,MaybeT
定义为:
newtype MaybeT m a =
MaybeT { runMaybeT :: m (Maybe a)}
但不是:
newtype MaybeT m a =
MaybeT { runMaybeT :: Maybe (m a) }
为什么是这样?
最佳答案
扩展新类型后,我们有 join :: Monad m => m (Maybe (m (Maybe a))) -> m (Maybe a)
在第一种情况下,join :: Monad m => Maybe (m (Maybe (m a))) -> Maybe (m a)
在第二。
实现第一个join
您需要一种分发方式Maybe
超过 m
: dist1 :: Monad m => Maybe (m a) -> m (Maybe a)
:
join1 :: m (Maybe (m (Maybe a))) -> m (Maybe a)
join1 = fmap join . join . fmap dist1
实现第二个
join
你需要相反的分配律dist2 :: Monad m => m (Maybe a) -> Maybe (m a)
join2 :: Maybe (m (Maybe (m a))) -> Maybe (m a)
join2 = fmap join . join . fmap dist2
dist1
很容易实现(我将证明 monad 更改器(mutator)定律留给你):dist1 :: Monad m => Maybe (m a) -> m (Maybe a)
dist1 = sequenceA
dist2
不是那么容易。它不能用于任意 Monad
.作为反例,我们选择 m
成为“读者”monad (->) r
:dist2 :: (r -> Maybe a) -> Maybe (r -> a)
由于您无权访问
r
,dist2
的唯一实现那将是 const Nothing
,这显然不满足单子(monad)定律。
关于haskell - 在 monad 转换器中,为什么已知的 monad 是内部的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46099700/