是否有可能实现MonadFix为`Free`?(Is it possible to implemen

2019-07-19 02:07发布

http://hackage.haskell.org/package/free在Control.Monad.Free.Free允许一个获得获得了“自由单子”对于任何给定Functor 。 这不,但是,有一个MonadFix实例。 这是因为这种情况下无法写入,或者它是否只是冷落?

如果这种情况不能写,为什么不呢?

Answer 1:

考虑什么样的描述mfix做:

一个一元计算的固定点。 mfix f执行动作f仅一次,用反馈作为输入的最终输出。

在“执行”二字,在上下文Free ,意味着创建的层Functor 。 因此,“只有一次”是指在评估的结果mfix f ,在保存的值Pure建设者必须完全确定如何创建仿函数的许多层。

现在,假设我们有一个特定的功能once我们知道将永远只能创建一个Free的构造,加上然而,许多Pure需要构造持有叶值。 的“曾经”的输出,那么,将是类型的值Free fa是同构型的一些价值fa 。 有了这些知识,我们可以这不同于Free的输出once安全,拿到类型的值fa

现在,请注意,由于mfix需要“执行动作只有一次”,结果mfix once应该,对于符合例如,不包含额外的一元结构比once在一个单一的应用程序创建。 因此,我们可以推断,从所获得的值mfix once也必须是同构的类型的值fa

考虑到与类型的任何功能的a -> fa一些Functor f ,我们可以换一个单一的结果Free和获得类型的函数a -> Free fa满足的描述once以上,我们已经建立了我们可以解开的结果mfix once拿到类型的值fa回。

因此,符合的实例(Functor f) => MonadFix (Free f)将意味着能够编写,通过缠绕和展开以上描述的那样,函数ffix :: (Functor f) => (a -> fa) -> fa那将工作的所有实例Functor

这显然不是说你不能写这样的实例证明......但如果有可能, MonadFix是完全多余的,因为你可以很容易地编写ffix直接。 (我想重新实现它作为mfix一个Monad约束,使用liftM 。哎。)



Answer 2:

好了,灵感来自MonadFix实例Maybe ,我想这一个(使用的下列定义Free ):

data Free f a
    = Pure a
    | Impure (f (Free f a))

instance (Functor f) => Monad (Free f) where
    return = Pure
    Pure x >>= f = f x
    Impure x >>= f = Impure (fmap (>>= f) x)

instance (Functor f) => MonadFix (Free f) where
    mfix f = let Pure x = f x in Pure x

法律是:

  • 纯度: mfix (return . h) = return (fix h)
  • 左收缩: mfix (\x -> a >>= \y -> fxy) = a >>= \y -> mfix (\x -> fxy)
  • 滑动: mfix (liftM h . f) = liftM h (mfix (f . h))对于严格h
  • 嵌套: mfix (\x -> mfix (fx)) = mfix (\x -> fxx)

纯度容易证明 - 但试图证明左萎缩,当我遇到一个问题就来了:

mfix (\x -> a >>= \y -> f x y)
= let Pure x = (\x -> a >>= \y -> f x y) x in Pure x
= let Pure x = a >>= \y -> f x y in Pure x
-- case a = Pure z
  = let Pure x = Pure z >>= \y -> f x y in Pure x
  = let Pure x = f x z in Pure x
  = let Pure x = (\x -> f x z) x in Pure x
  = mfix (\x -> f x z)
  = Pure z >>= \y -> mfix (\x -> f x y)
-- case a = Impure t
  = let Pure x = Impure t >>= \y -> f x y in Pure x
  = let Pure x = Impure (fmap (>>= \y -> f x y) t) in Pure x
  = Pure _|_

  Impure t >>= \y -> mfix (\x -> f x y)
  = Impure (fmap (>>= \y -> mfix (\x -> f x y)) t)
  /= Pure _|_

所以,在最起码,如果PureImpure的构造是可区分的,然后我实施mfix不符合法律。 我想不出任何其他实施,但这并不意味着它不存在。 抱歉,我不能进一步说明。



Answer 3:

不,它不能以通用,因为不是每个单子是MonadFix的一个实例。 每个单子可以使用下面的FreeMonad实现。 如果你可以实现免费的MonadFix,那么你就可以从任何单子,这是不可能得到MonadFix。 不过,当然,你可以定义MonadFix类FreeFix。

我认为它可能看起来在某种程度上是这样,但是这仅仅是一个猜测第3(仍然未测试):

data FreeFix m a = FreeFix { runFreeFix :: (forall r. (r -> m r) -> m r) -> m a }

instance (Monad m) => Monad (FreeFix m) where
    return a = FreeFix $ \_-> do
        return a
    f >>= g = FreeFix $ \mfx -> do
        x <- runFreeFix f mfx
        runFreeFix (g x) mfx

instance (Monad m) => MonadFix (FreeFix m) where
    mfix f = FreeFix $ \mfx -> do
        mfx (\r->runFreeFix (f r) mfx)

这个想法是,m是一个单子缺乏对MFIX的实施; 所以MFIX需要一个参数时FreeFix将减少。



文章来源: Is it possible to implement MonadFix for `Free`?