2011-08-09 6 views
15

は、多くの場合、あなたはpureなしApplicativeのようなもの、またはMonadのようなものを持っているが、returnなし。 semigroupoidパッケージは、これらのケースをApplyBindでカバーしています。今私はArrowに関する同様の状況にありますが、意味のあるarr関数を定義することはできませんが、他の関数は完全に意味をなさないと思います。カテゴリと矢印の間のタイプクラスは意味がありますか?

私は機能を保持し、それは逆の機能の型を定義した:

import Control.Category 

data Rev a b = Rev (a -> b) (b -> a) 

reverse (Rev f g) = Rev g f 
apply (Rev f _) x = f x 
applyReverse (Rev _ g) y = g y 
compose (Rev f f') (Rev g g') = Rev ((Prelude..) f g) ((Prelude..) g' f') 

instance Category Rev where 
    id = Rev Prelude.id Prelude.id 
    (.) x y = compose x y 

今私はArrowを実装することはできませんが、弱い何か:

--"Ow" is an "Arrow" without "arr" 
class Category a => Ow a where 
    first :: a b c -> a (b,d) (c,d) 
    first f = stars f Control.Category.id 

    second :: a b c -> a (d,b) (d,c) 
    second f = stars Control.Category.id f 

    --same as (***) 
    stars :: a b c -> a b' c' -> a (b,b') (c,c') 

... 
import Control.Arrow 

instance Ow Rev where 
    stars (Rev f f') (Rev g g') = Rev (f *** g) (f' *** g') 

私は実装できないと思います&&&と等価であり、f &&& g = arr (\b -> (b,b)) >>> f *** gと定義され、(\b -> (b,b))と定義されているので、これは可逆的ではありません。それでも、この弱いタイプのクラスが役に立つと思いますか?それは理論的な観点からも理にかなっていますか? 「:可逆プログラミングに矢印があると再び」:このアプローチはで調査した

+0

「矢印」はカテゴリの定義とまったく同じですか? –

+0

いいえ、 'Category'関数はカテゴリの定義です。私はそれを理解しているので、「カテゴリ」は同じオブジェクト(すべてのタイプ)を持っていますが、異なるモチーフを持つ** Hask **のサブカテゴリに対応しています。 'Arrow'はもっと多くの構造体を追加しますが、どのような構造体について言いたいのか分かりません。 –

+0

@Antal S-Z:実際にはサブカテゴリではありません。 'Category'は、オブジェクトが** Hask **のオブジェクトであり、2-ary型のコンストラクタによって与えられた矢印を持つカテゴリを指定します。 'Functor'は** Hask **のサブカテゴリを記述し、その矢印は** Hask **のものであり、オブジェクトは1-ary型のコンストラクタによって与えられます。 'Applicative'は'(、) 'の単層構造を' Functor'に写像し、 '(&&&)'などは 'Category'に写像します。 'arr'は** Hask **から' Category'にファンクタを与えます。 –

答えて

9

あなたに実行している正確な理由からhttp://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.153.9383

、これは取り上げていなかった悪いアプローチであることが判明しましたより広く。最近では、Tillmann Rendelは、可逆的な部分同型を置換した可逆的構文への楽しいアプローチを生み出した(http://www.informatik.uni-marburg.de/~rendel/rendel10invertible.pdf)。これは、人々が使用して遊ぶためのハックにパッケージ化されています:arrのない矢印は一定の意味を成していると思います。私はそのようなものが可逆関数を捕捉するのに適切な手段ではないと考えています。

編集:アダムMegaczの一般矢印(http://www.cs.berkeley.edu/~megacz/garrows/)もあります。これらは反転可能なプログラミングには役に立たないかもしれませんが(基本的な型クラスは逆行列であるように見えますが)、arrが強すぎる他の状況での使用がありますが、他の矢印操作が意味をなさないかもしれません。

8

カテゴリ理論の観点から、Categoryタイプのクラスは、タイプコンストラクタによってHaskellで矢印を直接記述できる任意のカテゴリを記述します。新しいプリミティブ矢印や矢印ビルディング関数の形でこの上に構築したいほとんどの追加機能は、総機能を使用して実装できる場合、ある程度意味をなさないでしょう。唯一の注意点は、表現力を追加すると、多くの場合arrで起こるように、他の要件を壊す可能性があることです。可逆機能の

あなたの具体的な例は、すべての矢印が同型写像されているカテゴリについて説明します。完全かつ完全に予想される衝撃的なひねりで、Edward Kmettは既にHackageにan implementation of thisを持っています。

arr関数は、ハスケル関数からファンク터(カテゴリ理論の意味で)におおよそ、Arrowインスタンスになり、オブジェクトは同じままです(つまり、型パラメータ)。単にArrowからarrを削除すると、あなたに...少なくともプリミティブとしてarr fstarr sndの当量を追加することなく、おそらく自分自身で非常に有用ではありません何かを与えます。

私は、二つの入力から新しい矢印を構築するために(&&&)とともに、fstsndのためのプリミティブを追加することが理論的な観点から、絶対に賢明である、productsであなたのカテゴリを与えるだけでなく、されてはならないと信じていますあなたが見つけた理由のために使用している可逆矢印と互換性があります。

+0

'Rev'(または' Iso')に '&&&'を書くための原則的な方法はありません。なぜ聞くの? 'b - > a'と' c - > a'はあなたの 'a-> b'と' a-> c'が '(b、c) *両方ともあなたのオリジナルの 'b'と' c'を返すことが保証されています。 – sclv

+0

同様に、Isoにも適切な 'fst'と' snd'を書くことはできません! (a、b) - > aの逆は何ですか?これは本当にあなたが部分同型写像を必要とする理由です。 (もちろん、第1と第2を書くこともできます)。 – sclv

+0

@sclv:はい。実際には、 '(***)'と '(+++)'の両方がうまくいっているだけでなく、積和型の連想型、可換型、分布型プロパティを与える関数でなければなりません。しかし '(&&&)'と '(|||)'は一般的な場合には機能しません。 –

関連する問題