我有一个coroutine变压器
data Step y m a = Done a | Yield y (CoT y m a) data CoT y m a = CoT (m (Step y m a))
与Monad
实例
unCoT :: CoT y m a -> m (Step y m a) unCoT (CoT m) = m instance Monad m => Monad (CoT y m) where return = CoT . return . Done CoT x >>= f = CoT $ do x' <- x case x' of Done a -> unCoT (f a) Yield y x' -> return (Yield y (x' >>= f))
如果我定义一个MFunctor
类Monad m
和 Monad n
约束我可以定义hoist
class MFunctor t where hoist :: (Monad n, Monad m) => (forall a. m a -> n a) -> t m b -> t n b instance MFunctor (CoT y) where hoist f (CoT m) = CoT $ do step <- f m return (case step of Done x -> Done x Yield y m' -> Yield y (hoist f m'))
但是mmorph
的hoist
只有一个Monad m
约束.hoist
没有它我可以定义我,还是缺乏一般性MFunctor
?
编辑:我发现它是可能的!但我的问题仍然存在:我们确定这里不乏普遍性吗?
instance MFunctor (CoT y) where hoist f (CoT m) = CoT $ f $ do step <- m return (case step of Done x -> Done x Yield y m' -> Yield y (hoist f m'))
Gabriel Gonz.. 8
mmorph
是在该pipes-3.*
系列的背景下开发的(它曾经是一个内部pipes
模块),其功能如下:
raise :: (Monad m, MFunctor t1, MonadTrans t2) => t1 m r -> t1 (t2 m) r raise = hoist lift
如果添加Monad n
约束,hoist
则必须添加Monad (t2 m)
约束raise
.我通常尝试最小化我的库中的约束,我找不到任何MFunctor
需要Monad n
约束的实例,所以我删除了它.
旁注:CoT y m a
与Producer y m a
from 相同pipes
,已经有一个MFunctor
实例.