据说,所有monad都可以使用Free
来表达(如果这不是真的,那么反例和原因是什么)?如何使用the continuation monad或Free
表达FreeT
或其相应的变换器 - 相应的仿函数是什么?或者,如果他们不能,那是什么原因?
更新:通过表达我的意思是基本上与Free F
同构,其中F
是一个仿函数我们&#39 ;重新寻找,例如Writer w
与Free ((,) w)
同构。
答案 0 :(得分:12)
延续monad 是您正在寻找的反例。我没有足够的知识来提供完整的证明,但我会给你几个参考资料。
这个想法是monad有一个" rank"与他们相关联。 "秩"粗略的意思 提供monad全部功能所需的操作数。
我怀疑,除了延续派生的monad之外,我们在Haskell中处理的所有monad都具有排名,例如Identity
,Maybe
,State s
,Either e
,......,以及他们通过变形金刚的组合。例如,Identity
由无操作生成,Maybe
由Nothing
,State s
由get
和put s
以及{{1}生成Either e
。 (也许这表明它们实际上都具有有限等级,或者可能Left e
计为每个put s
的不同操作,因此s
具有等级State s
的大小,我不确定。)
免费monad肯定有排名,因为s
由Free 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 m
或Free
的正常解释,我们可以拼凑出像FreeT
或Cont r
一样的怪物。例如,有一个ContT r
,Functor (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(当然)的(商)。所以现在你必须通过“表达”来准确地澄清你的意思。