http://hackage.haskell.org/package/free在Control.Monad.Free.Free
允许一个获得获得了“自由单子”对于任何给定Functor
。 这不,但是,有一个MonadFix
实例。 这是因为这种情况下无法写入,或者它是否只是冷落?
如果这种情况不能写,为什么不呢?
http://hackage.haskell.org/package/free在Control.Monad.Free.Free
允许一个获得获得了“自由单子”对于任何给定Functor
。 这不,但是,有一个MonadFix
实例。 这是因为这种情况下无法写入,或者它是否只是冷落?
如果这种情况不能写,为什么不呢?
考虑什么样的描述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
。哎。)
好了,灵感来自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 _|_
所以,在最起码,如果Pure
和Impure
的构造是可区分的,然后我实施mfix
不符合法律。 我想不出任何其他实施,但这并不意味着它不存在。 抱歉,我不能进一步说明。
不,它不能以通用,因为不是每个单子是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将减少。