2016-08-31 9 views
7

data Free f a = Pure a | Free (f (Free f a))を定義することができ、Functor f => Monad (Free f)です。Profunctorsのフリーモナドのアナログ

我々が定義する場合 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

だから、私はそれを考え出したと思う: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 

はhindthoughtで明らかに思えます。

+4

はい、profunctorsは追加の反変変数を持つファンクタです。あなたの 'T'は実際に' f'のプロフェッサーを使わず、functor-nessです:あなたは 'dimap'の最初の引数として' id'を使っています。 'T'は基本的に余分なパラメータを持つ' Free'です –

1

プロフェッショナルから無料のものを作るより適切な概念があります。それから、アナロジーで作業することができます。

集合Xによって生成される遊離のモノイドYは、方程式「Y = 1 + XY」の解として考えることができます。

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

F製品「FM」はの組成物である式「M = 1 + FM」の解決策として考えることができるファンクタによって生成されたフリーモナド、M、であるHaskellの表記ファンクタ。1がちょうどアイデンティティファンクタである。Haskellの表記でprofunctor Pから自由に何かを作る

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

は、溶液、Aは、 "A = 1 + PA"。製品 "PA" のようになるはずです標準はcomposition of profunctorsです.1は「アイデンティティ」プロファウンダ、(->)です。

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

これもprofunctorです:

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

しかし、実際にFree pは次のとおりです。

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) 

profunctorが強い場合はそのように無料版がありますか?実際にはpre-arrowと呼ばれるものです。制限、無料の強いprofunctorsは矢印のとおりです。直感的にあなたがb -ish事にa -ish事を取るようprofunctor P a bの要素を考えることができ

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' 

、標準的な例は、(->)によって与えられています。 Free Pは互換性のある(しかし観察できない)中間型のこれらの要素の評価されていない連鎖です。

+0

興味深いですが、なぜHask^op * Hask - > Haskの形式のprofunctorsに制限するのですか? – mnish

+0

@ mnish'cosこれはHaskellのProfunctor型クラスです。他のクラスへの一般化は練習として残されます。 – sigfpe