类比为Profunctors的免费monad

时间:2016-08-31 05:15:49

标签: haskell free-monad

我们可以定义data Free f a = Pure a | Free (f (Free f a)),因此Functor f => Monad (Free f)

如果我们定义 data T f a b = R a | S b | T (f a (T f a b))我们有一些类似的M所以Profunctor f => M (T f a),其中class Profunctor f where dimap :: (a -> b) -> (c -> d) -> f b c -> f a d

自从我注意到Data.Comp.Term.ContextFreeData.Comp.Param.Term.Context的潜在模拟同构时,我一直在想。

2 个答案:

答案 0 :(得分:2)

所以我想我明白了:M ~ Monad

instance Profunctor f => Functor (T f a) where
    fmap f (In m) = In (dimap id (fmap f) m)
    fmap f (Hole x) = Hole (f x)
    fmap f (Var v) = Var v

instance Profunctor f => Applicative (T f a) where
    pure = Hole
    (<*>) = ap

instance Profunctor f => Monad (T f a) where
    In m >>= f = In ((>>= f) <$> m)
    Hole x >>= f = f x
    Var v >>= _ = Var v
在pindthought中看起来很明显。

答案 1 :(得分:2)

有一个更合适的概念,就是从一个发展者那里获得一个免费的东西。然后我们可以通过类比来工作。

由集合X生成的自由幺半群Y可以被认为是等式的解决方案&#34; Y = 1 + XY&#34;。在Haskell表示法中

data List a = Nil | Cons a (List a)

由仿函数F生成的自由monad M可以被认为是等式的解决方案&#34; M = 1 + FM&#34;产品&#34; FM&#39;是仿函数的组成。 1只是身份仿函数。在Haskell表示法中

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

从一个profunctor P中取出一些东西应该看起来像一个解决方案,A,对于&#34; A = 1 + PA&#34;。产品&#34; PA&#34;是标准composition of profunctors。 1是&#34;身份&#34; profunctor,(->)。所以我们得到

data Free p a b = Pure (a -> b) | forall x.Free (p a x) (Free p x b)

这也是一个教练:

instance Profunctor b => Profunctor (Free b) where
    lmap f (Pure g) = Pure (g . f)
    lmap f (Free g h) = Free (lmap f g) h
    rmap f (Pure g) = Pure (f . g)
    rmap f (Free g h) = Free g (rmap f h)

如果测试者很强大,那么免费版本也是如此:

instance Strong p => Strong (Free p) where
    first' (Pure f) = Pure (first' f)
    first' (Free f g) = Free (first' f) (first' g)

但究竟是什么Free p?它实际上叫做pre-arrow。限制,自由强大的精灵是箭头:

instance Profunctor p => Category (Free p) where
    id = Pure id
    Pure f . Pure g = Pure (f . g)
    Free g h . Pure f = Free (lmap f g) h
    Pure f . Free g h = Free g (Pure f . h)
    f . Free g h = Free g (f . h)

instance (Profunctor p, Strong p) => Arrow (Free p) where
    arr = Pure
    first = first'

直观地说,你可以把一个profunctor P a b的一个元素想象成a - 是什么东西到b - ish的东西,这个规范的例子由{{1}给出}。 (->)是这些元素的未评估链,具有兼容(但不可观察)的中间类型。