以前の回答で、Petr Pudlak は HaskからHaskへCFunctor
のファンクター以外のファンクターのクラスを定義しました。型ファミリーを使用して少し書き直すと、次のようになります
class CFunctor f where
type Dom f :: * -> * -> * -- domain category
type Cod f :: * -> * -> * -- codomain category
cmap :: Dom f a b -> Cod f (f a) (f b) -- map morphisms across categories
たとえば、次のようなインスタンスで
instance CFunctor Maybe where
type Dom Maybe = (->) -- domain is Hask
type Cod Maybe = (->) -- codomain is also Hask
cmap f = \m -> case m of
Nothing -> Nothing
Just x -> Just (f x)
圏論では、F : C --> Dがファンクターであり、G : D --> Eがファンクターであるときはいつでも、合成GF : C --> Eもファンクターです。
これを Haskell で表現したいと思います。書くことができないのでinstance CFunctor (f . g)
、ラッパー クラスを紹介します。
newtype Wrap g f a = Wrap { unWrap :: g (f a) }
インスタンスを書くことで、CFunctor
私は限ります
instance (CFunctor f, CFunctor g, Cod f ~ Dom g) => CFunctor (Wrap g f) where
type Dom (Wrap g f) = Dom f
type Cod (Wrap g f) = Cod g
cmap = undefined
しかし、の実装がcmap
どうあるべきかわかりません。何かアドバイス?
PS、これらすべての最終的な理由はAdjunction
、メソッドunit
およびを含むクラスを導入し、counit
付加物からモナド インスタンスを自動的に派生させることです。しかし最初に、2 つのファンクターの合成もファンクターであることをコンパイラーに示す必要があります。
cmap.cmap
タイプのオブジェクトで使用でき、g (f a)
それが機能することはわかっていますが、それは少し不正行為のように思えます-確かにファンクターは単なるファンクターであり、コンパイラーはそれが実際に2つの構成であることを知る必要はありません他のファンクター?