如何使用免费monad表达延续monad?

时间:2014-09-13 20:15:58

标签: haskell monads continuations free-monad

据说,所有monad都可以使用Free来表达(如果这不是真的,那么反例和原因是什么)?如何使用the continuation monadFree表达FreeT或其相应的变换器 - 相应的仿函数是什么?或者,如果他们不能,那是什么原因?

更新:通过表达我的意思是基本上Free F 同构,其中F是一个仿函数我们&#39 ;重新寻找,例如Writer wFree ((,) w)同构。

4 个答案:

答案 0 :(得分:12)

延续monad 您正在寻找的反例。我没有足够的知识来提供完整的证明,但我会给你几个参考资料。

这个想法是monad有一个" rank"与他们相关联。 "秩"粗略的意思 提供monad全部功能所需的操作数。

我怀疑,除了延续派生的monad之外,我们在Haskell中处理的所有monad都具有排名,例如IdentityMaybeState sEither e,......,以及他们通过变形金刚的组合。例如,Identity由无操作生成,MaybeNothingState sgetput s以及{{1}生成Either e。 (也许这表明它们实际上都具有有限等级,或者可能Left e计为每个put s的不同操作,因此s具有等级State s的大小,我不确定。)

免费monad肯定有排名,因为sFree f编码的操作显式生成f

以下是排名的技术定义,但它不是很有启发性:http://journals.cambridge.org/action/displayAbstract?aid=4759448

在这里,您可以看到延续monad没有等级的声明:http://www.cs.bham.ac.uk/~hxt/cw04/hyland.pdf。我不确定他们是如何证明这一点的,但其含义是延续monad不是由任何操作集合生成的,因此不能表示为(一个)免费monad的商。

希望有人可以过来整理我的技术细节,但这是你想要的证明结构。

答案 1 :(得分:2)

my answer to a question of yours from last year。让我们考虑一下r = Bool(或者更常见的是允许非平凡自同构的任何类型r)。

m(最多为newtype包装器)定义为m :: (() -> Bool) -> Bool; m f = not (f ())。然后m非常重要,但m >> m是微不足道的。所以Cont Bool与自由monad不同构。

Haskell中的完整计算:

rwbarton@morphism:/tmp$ ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> import Control.Monad.Cont
Prelude Control.Monad.Cont> let m :: Cont Bool (); m = ContT (\f -> fmap not (f ()))
Loading package transformers-0.3.0.0 ... linking ... done.
Prelude Control.Monad.Cont> runCont m (const False) -- m not trivial
True
Prelude Control.Monad.Cont> runCont (m >> m) (const False)
False
Prelude Control.Monad.Cont> runCont (m >> m) (const True) -- (m >> m) trivial
True

答案 2 :(得分:1)

这里有几个小小的证据表明,Functor f并不存在,所有a :: *m :: * -> * FreeT f m a等同于{{ 1}}使用ContT r m a的正常解释。

FreeT使得没有实例m :: * -> *。由于Functor m,有一个实例instance Functor (ContT r m)。如果Functor (ConT r m)ContT r相同,我们会期望FreeT f。但是,使用Functor (FreeT f m)FreeT的常规解释,没有instance (Functor f, Functor m) => Functor (FreeT f m)实例,因为没有Functor (FreeT f m)实例。 (我放宽了对Functor m的正常解释,从要求FreeT到只需要Monad m,因为它只使用Functor m。)

liftM使得没有实例m :: * -> *。由于Monad m,有一个实例instance Monad (ContT r m)。如果Monad (ConT r m)ContT r相同,我们会期望FreeT f。但是,使用Monad (FreeT f m)FreeT的常规解释,没有instance (Functor f, Monad m) => Monad (FreeT f m)实例,因为没有Monad (FreeT f m)实例。

如果我们不想使用Monad mFree的正常解释,我们可以拼凑出像FreeTCont r一样的怪物。例如,有一个ContT rFunctor (f r)使用Free (f r) a的异常解释,即Cont r a,可以等同于Free

答案 3 :(得分:1)

这是一个愚蠢的答案,表明你的问题和我之前的答案都需要工作。

Cont可以使用Free轻松表达:

import Control.Monad.Free
import Control.Monad.Trans.Cont

type Cont' r = Free (Cont r)

quotient :: Cont' r a -> Cont r a
quotient = retract

Cont是自由monad(当然)的(商)。所以现在你必须通过“表达”来准确地澄清你的意思。