2016-04-29 5 views
11

objectiveパッケージの遊びの間、私は次のタイプが面白い特性を持っていることに気付きました。RankNTypesを使用するこのファンクタの名前は何ですか?

> {-# LANGUAGE RankNTypes #-} 
> data N f r = N { unN :: forall x. f x -> (x, r) } 

これはFunctorです。グーグル/ hoogleの数時間後

> instance Functor (N f) where 
> fmap f (N nat) = N $ fmap (fmap f) nat 
>   -- or, = N $ \fx -> let { (x,a) = nat fx } in (x, f a) 

、私はこのタイプを含む任意の 既存のモジュールを見つけることあきらめました。 このタイプは何ですか?よく知られている場合、名前は何ですか?役に立たなかったり無視したりしていますか?

Nは目的のパッケージに含まれるオブジェクトから派生したもので、これは私の100%オリジナルの作成ではありません。

> data Object f g = Object { 
>  runObject :: forall x. f x -> g (x, Object f g) 
> } 

N f修正が適用されたときにObject f Identityを生成ファンクタです。


このタイプについての事実は、私がそれが面白いと思った理由です。

Nは、ReaderからWriterに変換します。逆もまた同様です。 (ここで私はタイプ間の同型について(=)記号を使用)

N ((->) e) r 
= forall x. (e -> x) -> (x, r) 
= (e, r) 

N ((,) d) r 
= forall x. (d, x) -> (x, r) 
= d -> r 

NストアはStateモナドにcomonad変換しますが、逆は真ではありません。

> data Store s a = Store s (s -> a) 
> type State s a = s -> (s, a) 

N (Store s) r 
= forall x. (s, (s -> x)) -> (x, r) 
= forall x. s -> (s -> x) -> (x, r) 
= s -> (s, r) 
= State s r 

N (State s) r 
= forall x. (s -> (s, x)) -> (x, r) 
= forall x. (s -> s, s -> x) -> (x, r) 
= forall x. (s -> s) -> (s -> x) -> (x, r) 
= (s -> s) -> (s, r) -- ??? 

Nはおそらくかかりません。

N Maybe r 
= forall x. Maybe x -> (x, r) 
= forall x. (() -> (x, r), x -> (x, r)) 
= Void  -- because (() -> (x, r)) can't be implemented 

以下の機能が楽しいかもしれません。私はそれを逆にすることはできませんでした。

> data Cofree f a = Cofree a (f (Cofree f a)) 
> data Free f a = Pure a | Wrap (f (Free f a)) 

> unfree :: Free (N f) r -> N (Cofree f) r 
> unfree (Pure r) = N $ \(Cofree a _) -> (a, r) 
> unfree (Wrap n_f) = N $ 
> \(Cofree _ f) -> let (cofree', free') = unN n_f f 
>     in unN (unfree free') cofree' 

全文はHaskell(.lhs)です。

+2

私はそのための名前を知らないが、 'としてそれを書く(X forallをFX - 。>((、)R)x)'は、それは 'Control.Comonad.Cofreeに渡すことができるものとなります。ホイストフリー。 – Gurkenglas

+1

@chi「N」には「g」はありません。これは 'Object f g'に' g〜Identity'を設定しています。あなたが 'forall xから興味のない' Identity's'をドロップすると、 f x - >アイデンティティ(x、オブジェクトfアイデンティティ) 'あなたは' forall xを得る。 f x - >(x、Object f) 'である。 'Object f'の再帰的な出現を新しいパラメータ' r'で置き換えると、 'forall xを得ます。 f x - >(x、r) 'であり、これは「N f r」である。 'Fix(N f)'は 'r'があった場所に再帰的なオカレンスを戻します。 – Cirdec

+0

これは['Ran'](https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor-Ran.html#t:Ran)のように見えますが、プロファウンタとバイファイラを混在させて照合します。 'forall x。 f x - > x 'は' f 'のインデックスです。他の部分は 'forall xの環境からの読者です。 'f'の構造体を読み込みますが、その値は読みません。 – Cirdec

答えて

2

私はそれを「ハンドラ」ファンクタと呼びます。 Objectは、私が目的を解放する前にハンドラファンクタを使って定義していました。

ええと、このファンクタは興味深いです - Cofree (Handler f)にはパブリックゲッターがあり、Free (Handler f)mortal objectです。たぶん私はハンドラファンクタを出荷していたはずです...

1

すでに回答はありますが、私は自分自身で別の答えを見つけました。

タイプNは、次の記事で説明するタイプクラスPairingの値レベル表現でした。

Free for DSLs, cofree for interpreters

Cofree Comonads and the Expression Problem (ペアリングは、ここではデュアルと呼ばれている)

ペアリングとNは同じものです

ペアリングの定義は、このです。

> class Pairing f g where 
> pair :: (a -> b -> c) -> f a -> g b -> c 

fN fペアリングです。

> instance Pairing f (N f) where 
> pair k fa nb = uncurry k $ unN nb fa 

Nは、ペアリングの観点から表すことができる。

> data Counterpart f r = forall g. Pairing f g => Counterpart (g r) 
> 
> iso1 :: N f r -> Counterpart f r 
> iso1 = Counterpart 
> 
> iso2 :: Counterpart f r -> N f r 
> iso2 (Counterpart gr) = N $ \fx -> pair (,) fx gr 

unfreeに対応して無料-VS-Cofreeインスタンスは、があります。 その他の興味深いインスタンスも記事に定義されています。 PairingMへ

> instance Pairing f g => Pairing (Free f) (Cofree g) where 
> pair = undefined -- see link above 

拡張ペアリングは、モナドmの内部で計算を行うためにペアリングを拡張

元記事goes toをオブジェクトに。

> class PairingM f g m | f -> g, g -> f where 
> pairM :: (a -> b -> m r) -> f a -> g b -> m r 

PairingMをNに似た形式に書き換えると、オブジェクトが再び取得されます。

> -- Monad m => HandlerM' f m r ~ HandlerM f m r 
> data HandlerM' f m r = forall g. PairingM f g m => HandlerM' (g r) 
> data HandlerM f m r = HandleM { runHandlerM :: forall x. f x -> m (x, r) } 
> 
> -- Fix (HandlerM f m) ~ Object f m 
> -- Free (HandlerM f m) ~ (mortal Object from f to m)