为什么MFunctor的'提升机'没有'Monad n'限制? [英] Why does MFunctor's 'hoist' not have 'Monad n' constraint?

查看:113
本文介绍了为什么MFunctor的'提升机'没有'Monad n'限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个协程变换器

  data步骤y m a =完成a | Yield y(CoT yma)

data CoT yma = CoT(m(Step yma))

Monad 实例

  unCoT :: CoT yma - > m(步骤y m a)
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))
c $ c> MFunctor class with 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 的生产者yma ,它已经有一个 MFunctor 实例。


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 instance

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))

If I define an MFunctor class with Monad m and Monad n constraints I can define 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'))

But mmorph's hoist only has a Monad m constraint. Can I define my hoist without it, or is this a lack of generality of MFunctor?

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 the pipes-3.* series (it used to be an internal pipes 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 to hoist then you have to add a Monad (t2 m) constraint to raise. I generally try to minimize constraints in my libraries and I couldn't find any MFunctor instances that needed the Monad n constraint, so I removed it.

Side note: CoT y m a is the same thing as Producer y m a from pipes, which already has an MFunctor instance.

这篇关于为什么MFunctor的'提升机'没有'Monad n'限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆