为什么MFunctor的'提升机'没有'Monad n'限制? [英] Why does MFunctor's 'hoist' not have 'Monad n' constraint?
问题描述
我有一个协程变换器
data步骤y m a =完成a | Yield y(CoT yma)
data CoT yma = CoT(m(Step yma))
与 Monad
实例
unCoT :: CoT yma - > m(步骤y m a)
c $ c> MFunctor class with
unCoT(CoT m)= m
实例Monad m => Monad(CoT y m)其中
return = CoT。返回。完成
CoT x>> = f = CoT $ do
x'< - x
case x'of
完成a - > unCoT(f a)
收益y x' - >如果我定义了一个<$
$ b $ return $(yield y(x'>> = f))
Monad m
和Monad n
约束我可以定义hoist
class MFunctor t其中
hoist ::(Monad n,Monad m)=> (全部a - > a a) - > t m b - > tnb
instance MFunctor(CoT y)其中
hoist f(CoT m)= CoT $ do
step < - fm
return(case Done x - >完成x
收益y m' - >收益y(hoist f m'))
但是
mmorph
的hoist
只有一个Monad m
约束。我可以在没有它的情况下定义我的hoist
,或者这是缺乏一般性的MFunctor
?
编辑:我研究过它是可能的!但我的问题仍然存在:我们确定这里不缺乏一般性吗?
instance MFunctor(CoT y)其中
提升f(CoT m)= CoT $ f $ do
step < - m
return(完成x的情况步骤 - >完成x
收益y m' - >收益y(hoist f m'))
解决方案
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
。我通常会尽量减少库中的约束,并且找不到需要Monad n
约束的任何MFunctor
实例,所以我删除了它。
附注:
CoT yma
与来自
,它已经有一个pipes
的生产者ymaMFunctor
实例。I have a coroutine transformer
data Step y m a = Done a | Yield y (CoT y m a) data CoT y m a = CoT (m (Step y m a))
with
Monad
instanceunCoT :: 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))
If I define an
MFunctor
class withMonad m
andMonad n
constraints I can definehoist
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'))
But
mmorph
'shoist
only has aMonad m
constraint. Can I define myhoist
without it, or is this a lack of generality ofMFunctor
?EDIT: I worked out it is possible! But my question still stands: are we sure there's no lack of generality here?
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'))
解决方案
mmorph
was developed in the context of thepipes-3.*
series (it used to be an internalpipes
module), which had functions like this:raise :: (Monad m, MFunctor t1, MonadTrans t2) => t1 m r -> t1 (t2 m) r raise = hoist lift
If you add the
Monad n
constraint tohoist
then you have to add aMonad (t2 m)
constraint toraise
. I generally try to minimize constraints in my libraries and I couldn't find anyMFunctor
instances that needed theMonad n
constraint, so I removed it.Side note:
CoT y m a
is the same thing asProducer y m a
frompipes
, which already has anMFunctor
instance.这篇关于为什么MFunctor的'提升机'没有'Monad n'限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!