バイカテゴリの型クラスを定義し、カテゴリ、ファンクター、自然変換のバイカテゴリでインスタンス化しようとしています。
{-# LANGUAGE NoImplicitPrelude, MultiParamTypeClasses,
TypeOperators, KindSignatures, Rank2Types,
ScopedTypeVariables, FlexibleInstances, InstanceSigs #-}
カテゴリのクラスは次のとおりです。
class Category (c :: * -> * -> *) where
id :: c x x
(.) ::c y z -> c x y -> c x z
ファンクターのクラスは次のとおりです。
class Functor c d f where
fmap :: c x y -> d (f x) (f y)
ファンクターの構成は次のとおりです。
newtype Comp g f t = Comp (g (f t))
2つのファンクターの構成はファンクターである必要があります。ただし、次のインスタンス化は、範囲外であるためf
、Haskellでは受け入れられg
ません。fmap
ここでどのように定義しますか?
instance Functor c e (Comp g f) where
fmap :: c x y -> e (Comp g f x) (Comp g f y)
fmap = fmap g . fmap f
自然変換は次のとおりです(パラメーターcはここでは使用されませんが、以下の次のインスタンス化に役立ちます)。
newtype NT f g (c :: * -> * -> *) d =
NT {unNT :: forall x. d (f x) (g x) }
バイカテゴリのクラスは次のとおりです(演算子.|
と.-
はそれぞれ2セルの垂直方向と水平方向の構成です)。
class Bicategory
(bicat :: (* -> *) -> (* -> *) -> (* -> * -> *) -> (* -> * -> *) -> *)
comp where
id1 :: Category d => bicat f f c d
(.|) :: Category d => bicat g h c d -> bicat f g c d -> bicat f h c d
(.-) :: bicat g g' d e -> bicat f f' c d -> bicat (g `comp` f) (g' `comp` f') c e
カテゴリ、ファンクタ、および自然変換は、2つのカテゴリを形成する必要があります。ただし、次のインスタンス化はHaskellによって受け入れられ.-
ません。これは、自然変換の水平構成の定義では、gがスコープ内にないためです。(.-)
ここで水平方向の構成をどのように定義しますか?
instance Bicategory NT Comp where
id1 = NT id
n .| m = NT (unNT n . unNT m)
(n :: NT g g' d e) .- m = NT (unNT n . fmap g (unNT m))
のレコードゲッターを定義して、ファンクターの作成を少し簡単にしましょうCompose
(省略の必要はありません。私たちは友達の中にいます)。
newtype Compose g f t = Compose { unCompose :: g (f t) }
-- Compose :: g (f t) -> Compose g f t
-- unCompose :: Compose g f t -> g (f t)
を作成するにCompose g f
はFunctor c d
、関数をカテゴリに分類する方法が必要なので、次のようにd
定義しましょう。
class Category c => Arr c where
arr :: (x -> y) -> c x y -- stolen from Control.Arrow.Arrow
これで、必要なものがすべて揃いました。
instance (Functor c d f, Functor d e g, Arr e) => Functor c e (Compose g f) where
-- c :: c x y
-- fmap_cdf c :: d (f x) (f y)
-- fmap_deg (fmap_cdf c) :: e (g (f x)) (g (f y))
-- arr Compose :: e (g (f y)) (Compose g f y)
-- arr unCompose :: e (Compose g f x) (g (f x))
-- arr Compose . fmap_deg (fmap_cdf c) . arr unCompose
-- :: e (Compose g f x) (Compose g f y)
fmap c = arr Compose . fmap_deg (fmap_cdf c) . arr unCompose
where fmap_cdf :: forall x y. c x y -> d (f x) (f y)
fmap_cdf = fmap
fmap_deg :: forall x y. d x y -> e (g x) (g y)
fmap_deg = fmap
ここではAllowAmbiguousTypes
(GHC 7.8で)使用する必要があります。カテゴリd
が完全に消えて、あいまいになっているためです。
今のためにBicategory
。
単純化しましょうNT
-そのファントムパラメータは必要ありません。
newtype NT c f g = NT { unNT :: forall x. c (f x) (g x) }
これで、より簡単なBicategory
定義を作成できます。
class Bicategory (bicat :: (* -> * -> *) -> (* -> *) -> (* -> *) -> *) comp where
id1 :: Category c => bicat c f f
(.|) :: Category c => bicat c g h -> bicat c f g -> bicat c f h
(.-) :: (Functor c d g, Arr d) => bicat d g g' -> bicat c f f' -> bicat d (comp g f) (comp g' f')
実装できるもの:
instance Bicategory NT Compose where
id1 = NT id
NT n .| NT m = NT (n . m)
-- m :: c (f x) (f' x)
-- fmap m :: d (g (f x)) (g (f' x))
-- n :: d (g (f' x)) (g' (f' x))
-- n . fmap m :: d (g (f x)) (g' (f' x))
-- arr Compose :: d (g' (f' x)) (Compose g' f' x)
-- arr unCompose :: d (Compose g f x) (g (f x))
-- arr Compose . n . fmap m . arr unCompose
-- :: d (Compose g f x) (Compose g' f' x)
NT n .- NT m = NT $ arr Compose . n . fmap m . arr unCompose
これが完全なコードの要点です。GHC-7.8.2で正常にコンパイルされます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加