2015-09-21 7 views
6

を実装反変ファンクタは、以下が真であることを型クラスの機能反転

import Control.Category (Category, (.), id) 

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

instance Category Invertible where 
    id = Invertible Prelude.id Prelude.id 
    (Invertible f f') . (Invertible g g') = 
    Invertible (f Prelude.. g) (g' Prelude.. f') 

invert (Invertible x y) = Invertible y x 

注以下の私が持っているとしましょう私の場合は

F(g . f) = F(f) . F(g) 

、:それは同じ公理を次のようにcontravariant functor (wikipedia)、は単純にinvertです。

私はData.Functor.Contravariant.contramapを見て、種類の機能を有している:

(a -> b) -> f b -> f a 

をしかし、私は、私は私の状況でそれを実装したいhow'dを知りませんでした。たとえば、私はfのための賢明な選択肢を働くことはできません、そして私の状況では、機能はありませんa -> b、ちょうどinvert

しかし、invertでも反例のあるファンクタの数学的公理に合っているので、これを既存のクラスに適合させることができると思っていますが、どのクラスとその方法を見つけることができません。どのような助けや指針をいただければ幸いです。

+1

このブログの記事は面白いかもしれません:http://gelisam.blogspot.com/2013/07/the-commutative-monad.html –

+2

私の謙虚な意見では、問題は、「逆さま」は反変的な内書人です'逆変態f 'は'ハス 'のカテゴリの反変的な内分泌者である。 –

+0

@AaditMShah、それも私の推測でしたが、十分なカテゴリ理論が自信を持っているかどうかはわかりません。 – dfeuer

答えて

8

カテゴリには、オブジェクトとモーフの2つのコレクションがあります。

通常のHaskellの前奏曲、そして、Data.Functor.Contravariantのクラスは、非常に狭いカテゴリーで動作するように見える、それは型がオブジェクトであり、関数は射ているカテゴリーです、通常Haskを表します。標準Functorクラスも非常に狭く、内科用医師Haskを表しています。型と機能を関数に渡す必要があります。

例えば、ファンクタMaybeをとります。タイプにMaybeが作用する方法は、aからMaybe aまでのタイプが必要です。 MaybeIntからMaybe Intなどのようにマップします(これはちょっと些細なことです)。それはfmapによってコードされる射する何:fmapはHaskに、2つのオブジェクト間の射をf :: (a -> b)取り、fmap f :: (Maybe a -> Maybe b)にマップ、オブジェクト間の内の別の射Haskそのファンクタマップがします。ハスケルでは、Functorを定義することはできませんでした。 IntChar - すべてHaskell Functorはタイプコンストラクタでなければなりませんが、一般的なカテゴリ理論では可能です。

Control.Categoryは少し一般化:Control.CategoryカテゴリCのオブジェクトは、[1]同じようでHaskまだ種類がありますが、その射型C a bのものです。したがって、あなたの例では、オブジェクトは依然として任意の型ですが、あなたのモーフはタイプInvertible a bです。あなたのモーフは関数ではないので、標準のFunctorクラスを使用することはできません。

しかし、それはCategoryカテゴリではなく、あなたの例をキャプチャしますHaskを、仮定の間で動作数子のクラスを定義するために、あなたの圏論のノウハウを構築で楽しいエクササイズです。ファンクタはオブジェクト(型)のモーフに作用することを忘れないでください。

私はあなたにそれを残します - あなたが多くのガイダンスをしたいと思ったらコメントしてください。


[1] PolyKindsを無視します。これは少し一般的です。

+0

あなたはそれに私を打つ。 OPが「Prelude.id」と「Control.Category.id」と「Prelude..」と「Control.Category..」を結婚しようとしていたために問題が発生していることは分かっていましたが、答えを書いてください。私は次のブログ記事で迷ってしまった:http://gelisam.blogspot.com/2013/07/the-commutative-monad.html –

+2

Control.Categorical.fmapにあるものを取り除くと言うと 'rab - > t(fa)(fb) 'となる。代わりに 'contramap :: r a b - > t(f b)(f a)'にすることができます。 r =可逆、t =可逆とする。ここから 'contramap :: Invertible a b - > Invertible(f b)(f a)'が得られます。私はこの時点で "f"が必要なのではないでしょうか? – Clinton

+0

@Clinton確かに。あなたは 'class(Category c、Category d)=> Contravariant f c d |を定義するでしょう。 f c→d、f d→cここでcontramap :: c x y→d(f y)(f x) 'である。次に、contramap(Invertible f g)= Invertible(Identity。g。runIdentity)(Identity。f。runIdentity) 'インスタンスContravariant Identity Invertible Invertibleを定義します。今度は 'contramap'と' invert'が同形です。しかし、不要な 'Identity'ラッパーを扱わなければならないので、' contramap'を使いたいと思っています。単純に 'invert'関数を直接使うのが良いでしょう。 –