-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Category theory -- -- Data-category is a collection of categories, and some categorical -- constructions on them. -- -- You can restrict the types of the objects of your category by using a -- GADT for the arrow type. To be able to proof to the compiler that a -- type is an object in some category, objects also need to be -- represented at the value level. The corresponding identity arrow of -- the object is used for that. -- -- See the Boolean and Product categories for some -- examples. -- -- Note: Strictly speaking this package defines Hask-enriched categories, -- not ordinary categories (which are Set-enriched.) In practice this -- means we are allowed to ignore undefined (f.e. when talking -- about uniqueness of morphisms), and we can treat the categories as -- normal categories. @package data-category @version 0.7 module Data.Category -- | An instance of Category k declares the arrow k as a -- category. class Category k src :: Category k => k a b -> Obj k a tgt :: Category k => k a b -> Obj k b (.) :: Category k => k b c -> k a b -> k a c -- | Whenever objects are required at value level, they are represented by -- their identity arrows. type Obj k a = k a a data Op k a b Op :: k b a -> Op k a b [unOp] :: Op k a b -> k b a instance Data.Category.Category (->) instance Data.Category.Category k => Data.Category.Category (Data.Category.Op k) module Data.Category.Product data (:**:) :: (* -> * -> *) -> (* -> * -> *) -> * -> * -> * [:**:] :: c1 a1 b1 -> c2 a2 b2 -> (:**:) c1 c2 (a1, a2) (b1, b2) -- | The product category of category c1 and c2. instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Category (c1 Data.Category.Product.:**: c2) module Data.Category.Functor -- | Functors are arrows in the category Cat. data Cat :: * -> * -> * [CatA] :: (Functor ftag, Category (Dom ftag), Category (Cod ftag)) => ftag -> Cat (CatW (Dom ftag)) (CatW (Cod ftag)) -- | We need a wrapper here because objects need to be of kind *, and -- categories are of kind * -> * -> *. data CatW :: (* -> * -> *) -> * -- | Functors map objects and arrows. class (Category (Dom ftag), Category (Cod ftag)) => Functor ftag where type Dom ftag :: * -> * -> * type Cod ftag :: * -> * -> * type (:%) ftag a :: * where { type family Dom ftag :: * -> * -> *; type family Cod ftag :: * -> * -> *; type family (:%) ftag a :: *; } -- | % maps arrows. (%) :: Functor ftag => ftag -> Dom ftag a b -> Cod ftag (ftag :% a) (ftag :% b) data Id (k :: * -> * -> *) Id :: Id data (:.:) g h [:.:] :: (Functor g, Functor h, Cod h ~ Dom g) => g -> h -> g :.: h data Const (c1 :: * -> * -> *) (c2 :: * -> * -> *) x [Const] :: Obj c2 x -> Const c1 c2 x -- | The constant functor with the same domain and codomain as f. type ConstF f = Const (Dom f) (Cod f) data Opposite f [Opposite] :: Functor f => f -> Opposite f data OpOp (k :: * -> * -> *) OpOp :: OpOp data OpOpInv (k :: * -> * -> *) OpOpInv :: OpOpInv data Proj1 (c1 :: * -> * -> *) (c2 :: * -> * -> *) Proj1 :: Proj1 data Proj2 (c1 :: * -> * -> *) (c2 :: * -> * -> *) Proj2 :: Proj2 data (:***:) f1 f2 (:***:) :: f1 -> f2 -> (:***:) f1 f2 data DiagProd (k :: * -> * -> *) DiagProd :: DiagProd type Tuple1 c1 c2 a = (Const c2 c1 a :***: Id c2) :.: DiagProd c2 -- | Tuple1 tuples with a fixed object on the left. tuple1 :: (Category c1, Category c2) => Obj c1 a -> Tuple1 c1 c2 a type Tuple2 c1 c2 a = Swap c2 c1 :.: Tuple1 c2 c1 a -- | Tuple2 tuples with a fixed object on the right. tuple2 :: (Category c1, Category c2) => Obj c2 a -> Tuple2 c1 c2 a type Swap (c1 :: * -> * -> *) (c2 :: * -> * -> *) = (Proj2 c1 c2 :***: Proj1 c1 c2) :.: DiagProd (c1 :**: c2) -- | swap swaps the 2 categories of the product of categories. swap :: (Category c1, Category c2) => Swap c1 c2 data Hom (k :: * -> * -> *) Hom :: Hom type (:*-:) x k = Hom k :.: Tuple1 (Op k) k x -- | The covariant functor Hom(X,--) homX_ :: Category k => Obj k x -> x :*-: k type (:-*:) k x = Hom k :.: Tuple2 (Op k) k x -- | The contravariant functor Hom(--,X) hom_X :: Category k => Obj k x -> k :-*: x type HomF f g = Hom (Cod f) :.: (Opposite f :***: g) homF :: (Functor f, Functor g, Cod f ~ Cod g) => f -> g -> HomF f g type Star f = HomF (Id (Cod f)) f star :: Functor f => f -> Star f type Costar f = HomF f (Id (Cod f)) costar :: Functor f => f -> Costar f instance Data.Category.Category Data.Category.Functor.Cat instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Functor.Id k) instance (Data.Category.Category (Data.Category.Functor.Cod g), Data.Category.Category (Data.Category.Functor.Dom h)) => Data.Category.Functor.Functor (g Data.Category.Functor.:.: h) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Functor.Const c1 c2 x) instance (Data.Category.Category (Data.Category.Functor.Dom f), Data.Category.Category (Data.Category.Functor.Cod f)) => Data.Category.Functor.Functor (Data.Category.Functor.Opposite f) instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Functor.OpOp k) instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Functor.OpOpInv k) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Functor.Proj1 c1 c2) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Functor.Proj2 c1 c2) instance (Data.Category.Functor.Functor f1, Data.Category.Functor.Functor f2) => Data.Category.Functor.Functor (f1 Data.Category.Functor.:***: f2) instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Functor.DiagProd k) instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Functor.Hom k) module Data.Category.NaturalTransformation -- | f :~> g is a natural transformation from functor f to -- functor g. type (:~>) f g = forall c d. (c ~ Dom f, c ~ Dom g, d ~ Cod f, d ~ Cod g) => Nat c d f g -- | A component for an object z is an arrow from F z to -- G z. type Component f g z = Cod f (f :% z) (g :% z) -- | 'n ! a' returns the component for the object a of a natural -- transformation n. This can be generalized to any arrow -- (instead of just identity arrows). (!) :: (Category c, Category d) => Nat c d f g -> c a b -> d (f :% a) (g :% b) infixl 9 ! -- | Horizontal composition of natural transformations. o :: (Category c, Category d, Category e) => Nat d e j k -> Nat c d f g -> Nat c e (j :.: f) (k :.: g) -- | The identity natural transformation of a functor. natId :: Functor f => f -> Nat (Dom f) (Cod f) f f srcF :: Nat c d f g -> f tgtF :: Nat c d f g -> g -- | Natural transformations are built up of components, one for each -- object z in the domain category of f and g. data Nat :: (* -> * -> *) -> (* -> * -> *) -> * -> * -> * [Nat] :: (Functor f, Functor g, c ~ Dom f, c ~ Dom g, d ~ Cod f, d ~ Cod g) => f -> g -> (forall z. Obj c z -> Component f g z) -> Nat c d f g -- | The category of endofunctors. type Endo k = Nat k k type Presheaves k = Nat (Op k) (->) type Profunctors c d = Nat (Op d :**: c) (->) compAssoc :: (Functor f, Functor g, Functor h, Dom f ~ Cod g, Dom g ~ Cod h) => f -> g -> h -> Nat (Dom h) (Cod f) ((f :.: g) :.: h) (f :.: (g :.: h)) compAssocInv :: (Functor f, Functor g, Functor h, Dom f ~ Cod g, Dom g ~ Cod h) => f -> g -> h -> Nat (Dom h) (Cod f) (f :.: (g :.: h)) ((f :.: g) :.: h) idPrecomp :: Functor f => f -> Nat (Dom f) (Cod f) (f :.: Id (Dom f)) f idPrecompInv :: Functor f => f -> Nat (Dom f) (Cod f) f (f :.: Id (Dom f)) idPostcomp :: Functor f => f -> Nat (Dom f) (Cod f) (Id (Cod f) :.: f) f idPostcompInv :: Functor f => f -> Nat (Dom f) (Cod f) f (Id (Cod f) :.: f) constPrecompIn :: Nat j d (f :.: Const j c x) g -> Nat j d (Const j d (f :% x)) g constPrecompOut :: Nat j d f (g :.: Const j c x) -> Nat j d f (Const j d (g :% x)) constPostcompIn :: Nat j d (Const k d x :.: f) g -> Nat j d (Const j d x) g constPostcompOut :: Nat j d f (Const k d x :.: g) -> Nat j d f (Const j d x) data FunctorCompose (c :: * -> * -> *) (d :: * -> * -> *) (e :: * -> * -> *) FunctorCompose :: FunctorCompose -- | Composition of endofunctors is a functor. type EndoFunctorCompose k = FunctorCompose k k k -- | Precompose f e is the functor such that Precompose f e :% -- g = g :.: f, for functors g that compose with f -- and with codomain e. type Precompose f e = FunctorCompose (Dom f) (Cod f) e :.: Tuple2 (Nat (Cod f) e) (Nat (Dom f) (Cod f)) f precompose :: (Category e, Functor f) => f -> Precompose f e -- | Postcompose f c is the functor such that Postcompose f c -- :% g = f :.: g, for functors g that compose with -- f and with domain c. type Postcompose f c = FunctorCompose c (Dom f) (Cod f) :.: Tuple1 (Nat (Dom f) (Cod f)) (Nat c (Dom f)) f postcompose :: (Category e, Functor f) => f -> Postcompose f e data Wrap f h Wrap :: f -> h -> Wrap f h data Apply (c1 :: * -> * -> *) (c2 :: * -> * -> *) Apply :: Apply data Tuple (c1 :: * -> * -> *) (c2 :: * -> * -> *) Tuple :: Tuple instance Data.Category.Category d => Data.Category.Category (Data.Category.NaturalTransformation.Nat c d) instance (Data.Category.Category c, Data.Category.Category d, Data.Category.Category e) => Data.Category.Functor.Functor (Data.Category.NaturalTransformation.FunctorCompose c d e) instance (Data.Category.Functor.Functor f, Data.Category.Functor.Functor h) => Data.Category.Functor.Functor (Data.Category.NaturalTransformation.Wrap f h) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.NaturalTransformation.Apply c1 c2) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.NaturalTransformation.Tuple c1 c2) module Data.Category.RepresentableFunctor data Representable f repObj Representable :: f -> Obj (Dom f) repObj -> (forall k z. (Dom f ~ k, Cod f ~ (->)) => Obj k z -> f :% z -> k repObj z) -> (forall k. (Dom f ~ k, Cod f ~ (->)) => f :% repObj) -> Representable f repObj [representedFunctor] :: Representable f repObj -> f [representingObject] :: Representable f repObj -> Obj (Dom f) repObj [represent] :: Representable f repObj -> forall k z. (Dom f ~ k, Cod f ~ (->)) => Obj k z -> f :% z -> k repObj z [universalElement] :: Representable f repObj -> forall k. (Dom f ~ k, Cod f ~ (->)) => f :% repObj unrepresent :: (Functor f, Dom f ~ k, Cod f ~ (->)) => Representable f repObj -> k repObj z -> f :% z covariantHomRepr :: Category k => Obj k x -> Representable (x :*-: k) x contravariantHomRepr :: Category k => Obj k x -> Representable (k :-*: x) x type InitialUniversal x u a = Representable ((x :*-: Cod u) :.: u) a -- | An initial universal property, a universal morphism from x to u. initialUniversal :: Functor u => u -> Obj (Dom u) a -> Cod u x (u :% a) -> (forall y. Obj (Dom u) y -> Cod u x (u :% y) -> Dom u a y) -> InitialUniversal x u a type TerminalUniversal x u a = Representable ((Cod u :-*: x) :.: Opposite u) a -- | A terminal universal property, a universal morphism from u to x. terminalUniversal :: Functor u => u -> Obj (Dom u) a -> Cod u (u :% a) x -> (forall y. Obj (Dom u) y -> Cod u (u :% y) x -> Dom u y a) -> TerminalUniversal x u a module Data.Category.Adjunction data Adjunction c d f g Adjunction :: f -> g -> Profunctors c d (Costar f) (Star g) -> Profunctors c d (Star g) (Costar f) -> Adjunction c d f g [leftAdjoint] :: Adjunction c d f g -> f [rightAdjoint] :: Adjunction c d f g -> g [leftAdjunctN] :: Adjunction c d f g -> Profunctors c d (Costar f) (Star g) [rightAdjunctN] :: Adjunction c d f g -> Profunctors c d (Star g) (Costar f) mkAdjunction :: (Functor f, Functor g, Dom f ~ d, Cod f ~ c, Dom g ~ c, Cod g ~ d) => f -> g -> (forall a b. Obj d a -> c (f :% a) b -> d a (g :% b)) -> (forall a b. Obj c b -> d a (g :% b) -> c (f :% a) b) -> Adjunction c d f g mkAdjunctionUnits :: (Functor f, Functor g, Dom f ~ d, Cod f ~ c, Dom g ~ c, Cod g ~ d) => f -> g -> (forall a. Obj d a -> Component (Id d) (g :.: f) a) -> (forall a. Obj c a -> Component (f :.: g) (Id c) a) -> Adjunction c d f g leftAdjunct :: Adjunction c d f g -> Obj d a -> c (f :% a) b -> d a (g :% b) rightAdjunct :: Adjunction c d f g -> Obj c b -> d a (g :% b) -> c (f :% a) b adjunctionUnit :: Adjunction c d f g -> Nat d d (Id d) (g :.: f) adjunctionCounit :: Adjunction c d f g -> Nat c c (f :.: g) (Id c) idAdj :: Category k => Adjunction k k (Id k) (Id k) composeAdj :: Adjunction d e f g -> Adjunction c d f' g' -> Adjunction c e (f' :.: f) (g :.: g') data AdjArrow c d [AdjArrow] :: (Category c, Category d) => Adjunction c d f g -> AdjArrow (CatW c) (CatW d) initialPropAdjunction :: forall f g c d. (Functor f, Functor g, Dom f ~ d, Cod f ~ c, Dom g ~ c, Cod g ~ d) => f -> g -> (forall y. Obj d y -> InitialUniversal y g (f :% y)) -> Adjunction c d f g terminalPropAdjunction :: forall f g c d. (Functor f, Functor g, Dom f ~ d, Cod f ~ c, Dom g ~ c, Cod g ~ d) => f -> g -> (forall x. Obj c x -> TerminalUniversal x f (g :% x)) -> Adjunction c d f g adjunctionInitialProp :: Adjunction c d f g -> Obj d y -> InitialUniversal y g (f :% y) adjunctionTerminalProp :: Adjunction c d f g -> Obj c x -> TerminalUniversal x f (g :% x) precomposeAdj :: Category e => Adjunction c d f g -> Adjunction (Nat c e) (Nat d e) (Precompose g e) (Precompose f e) postcomposeAdj :: Category e => Adjunction c d f g -> Adjunction (Nat e c) (Nat e d) (Postcompose f e) (Postcompose g e) contAdj :: Adjunction (Op (->)) (->) (Opposite ((->) :-*: r) :.: OpOpInv (->)) ((->) :-*: r) instance Data.Category.Category Data.Category.Adjunction.AdjArrow module Data.Category.Unit data Unit a b [Unit] :: Unit () () -- | Unit is the category with one object. instance Data.Category.Category Data.Category.Unit.Unit module Data.Category.Coproduct data I1 a data I2 a data (:++:) :: (* -> * -> *) -> (* -> * -> *) -> * -> * -> * [I1] :: c1 a1 b1 -> (:++:) c1 c2 (I1 a1) (I1 b1) [I2] :: c2 a2 b2 -> (:++:) c1 c2 (I2 a2) (I2 b2) -- | The coproduct category of categories c1 and c2. data Inj1 (c1 :: * -> * -> *) (c2 :: * -> * -> *) Inj1 :: Inj1 -- | Inj1 is a functor which injects into the left category. data Inj2 (c1 :: * -> * -> *) (c2 :: * -> * -> *) Inj2 :: Inj2 -- | Inj2 is a functor which injects into the right category. data (:+++:) f1 f2 (:+++:) :: f1 -> f2 -> (:+++:) f1 f2 -- | f1 :+++: f2 is the coproduct of the functors f1 and -- f2. data CodiagCoprod (k :: * -> * -> *) CodiagCoprod :: CodiagCoprod -- | CodiagCoprod is the codiagonal functor for coproducts. data Cotuple1 (c1 :: * -> * -> *) (c2 :: * -> * -> *) a Cotuple1 :: (Obj c1 a) -> Cotuple1 a -- | Cotuple1 projects out to the left category, replacing a value -- from the right category with a fixed object. data Cotuple2 (c1 :: * -> * -> *) (c2 :: * -> * -> *) a Cotuple2 :: (Obj c2 a) -> Cotuple2 a -- | Cotuple2 projects out to the right category, replacing a value -- from the left category with a fixed object. data (:>>:) :: (* -> * -> *) -> (* -> * -> *) -> * -> * -> * [I1A] :: c1 a1 b1 -> (:>>:) c1 c2 (I1 a1) (I1 b1) [I12] :: Obj c1 a -> Obj c2 b -> (:>>:) c1 c2 (I1 a) (I2 b) [I2A] :: c2 a2 b2 -> (:>>:) c1 c2 (I2 a2) (I2 b2) -- | The directed coproduct category of categories c1 and -- c2. data NatAsFunctor f g NatAsFunctor :: (Nat (Dom f) (Cod f) f g) -> NatAsFunctor f g -- | A natural transformation Nat c d is isomorphic to a functor -- from c :**: 2 to d. instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Category (c1 Data.Category.Coproduct.:++: c2) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Coproduct.Inj1 c1 c2) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Coproduct.Inj2 c1 c2) instance (Data.Category.Functor.Functor f1, Data.Category.Functor.Functor f2) => Data.Category.Functor.Functor (f1 Data.Category.Coproduct.:+++: f2) instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Coproduct.CodiagCoprod k) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Coproduct.Cotuple1 c1 c2 a1) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Functor.Functor (Data.Category.Coproduct.Cotuple2 c1 c2 a2) instance (Data.Category.Category c1, Data.Category.Category c2) => Data.Category.Category (c1 Data.Category.Coproduct.:>>: c2) instance (Data.Category.Functor.Functor f, Data.Category.Functor.Functor g, Data.Category.Functor.Dom f ~ Data.Category.Functor.Dom g, Data.Category.Functor.Cod f ~ Data.Category.Functor.Cod g) => Data.Category.Functor.Functor (Data.Category.Coproduct.NatAsFunctor f g) module Data.Category.Void data Void a b magic :: Void a b -> x -- | Void is the category with no objects. voidNat :: (Functor f, Functor g, Dom f ~ Void, Dom g ~ Void, Cod f ~ d, Cod g ~ d) => f -> g -> Nat Void d f g data Magic (k :: * -> * -> *) Magic :: Magic -- | Since there is nothing to map in Void, there's a functor from -- it to any other category. instance Data.Category.Category Data.Category.Void.Void instance Data.Category.Category k => Data.Category.Functor.Functor (Data.Category.Void.Magic k) module Data.Category.Limit data Diag :: (* -> * -> *) -> (* -> * -> *) -> * [Diag] :: Diag j k -- | The diagonal functor with the same domain and codomain as f. type DiagF f = Diag (Dom f) (Cod f) -- | A cone from N to F is a natural transformation from the constant -- functor to N to F. type Cone f n = Nat (Dom f) (Cod f) (ConstF f n) f -- | A co-cone from F to N is a natural transformation from F to the -- constant functor to N. type Cocone f n = Nat (Dom f) (Cod f) f (ConstF f n) -- | The vertex (or apex) of a cone. coneVertex :: Cone f n -> Obj (Cod f) n -- | The vertex (or apex) of a co-cone. coconeVertex :: Cocone f n -> Obj (Cod f) n -- | Limits in a category k by means of a diagram of type -- j, which is a functor from j to k. type Limit f = LimitFam (Dom f) (Cod f) f -- | An instance of HasLimits j k says that k has all -- limits of type j. class (Category j, Category k) => HasLimits j k -- | limit returns the limiting cone for a functor f. limit :: HasLimits j k => Obj (Nat j k) f -> Cone f (Limit f) -- | limitFactorizer shows that the limiting cone is universal – -- i.e. any other cone of f factors through it by returning the -- morphism between the vertices of the cones. limitFactorizer :: HasLimits j k => Obj (Nat j k) f -> (forall n. Cone f n -> k n (Limit f)) data LimitFunctor (j :: * -> * -> *) (k :: * -> * -> *) LimitFunctor :: LimitFunctor -- | The limit functor is right adjoint to the diagonal functor. limitAdj :: forall j k. HasLimits j k => Adjunction (Nat j k) k (Diag j k) (LimitFunctor j k) rightAdjointPreservesLimits :: (HasLimits j c, HasLimits j d) => Adjunction c d f g -> Obj (Nat j c) t -> d (Limit (g :.: t)) (g :% Limit t) rightAdjointPreservesLimitsInv :: (HasLimits j c, HasLimits j d) => Obj (Nat c d) g -> Obj (Nat j c) t -> d (g :% Limit t) (Limit (g :.: t)) -- | Colimits in a category k by means of a diagram of type -- j, which is a functor from j to k. type Colimit f = ColimitFam (Dom f) (Cod f) f -- | An instance of HasColimits j k says that k has all -- colimits of type j. class (Category j, Category k) => HasColimits j k -- | colimit returns the limiting co-cone for a functor f. colimit :: HasColimits j k => Obj (Nat j k) f -> Cocone f (Colimit f) -- | colimitFactorizer shows that the limiting co-cone is universal -- – i.e. any other co-cone of f factors through it by returning -- the morphism between the vertices of the cones. colimitFactorizer :: HasColimits j k => Obj (Nat j k) f -> (forall n. Cocone f n -> k (Colimit f) n) data ColimitFunctor (j :: * -> * -> *) (k :: * -> * -> *) ColimitFunctor :: ColimitFunctor -- | The colimit functor is left adjoint to the diagonal functor. colimitAdj :: forall j k. HasColimits j k => Adjunction k (Nat j k) (ColimitFunctor j k) (Diag j k) leftAdjointPreservesColimits :: (HasColimits j c, HasColimits j d) => Adjunction c d f g -> Obj (Nat j d) t -> c (f :% Colimit t) (Colimit (f :.: t)) leftAdjointPreservesColimitsInv :: (HasColimits j c, HasColimits j d) => Obj (Nat d c) f -> Obj (Nat j d) t -> c (Colimit (f :.: t)) (f :% Colimit t) class Category k => HasTerminalObject k where type TerminalObject k :: * where { type family TerminalObject k :: *; } terminalObject :: HasTerminalObject k => Obj k (TerminalObject k) terminate :: HasTerminalObject k => Obj k a -> k a (TerminalObject k) class Category k => HasInitialObject k where type InitialObject k :: * where { type family InitialObject k :: *; } initialObject :: HasInitialObject k => Obj k (InitialObject k) initialize :: HasInitialObject k => Obj k a -> k (InitialObject k) a data Zero class Category k => HasBinaryProducts k where type BinaryProduct (k :: * -> * -> *) x y :: * l *** r = (l . proj1 (src l) (src r)) &&& (r . proj2 (src l) (src r)) where { type family BinaryProduct (k :: * -> * -> *) x y :: *; } proj1 :: HasBinaryProducts k => Obj k x -> Obj k y -> k (BinaryProduct k x y) x proj2 :: HasBinaryProducts k => Obj k x -> Obj k y -> k (BinaryProduct k x y) y (&&&) :: HasBinaryProducts k => k a x -> k a y -> k a (BinaryProduct k x y) (***) :: HasBinaryProducts k => k a1 b1 -> k a2 b2 -> k (BinaryProduct k a1 a2) (BinaryProduct k b1 b2) data ProductFunctor (k :: * -> * -> *) ProductFunctor :: ProductFunctor data (:*:) p q [:*:] :: (Functor p, Functor q, Dom p ~ Dom q, Cod p ~ k, Cod q ~ k, HasBinaryProducts k) => p -> q -> p :*: q -- | A specialisation of the limit adjunction to products. prodAdj :: HasBinaryProducts k => Adjunction (k :**: k) k (DiagProd k) (ProductFunctor k) class Category k => HasBinaryCoproducts k where type BinaryCoproduct (k :: * -> * -> *) x y :: * l +++ r = (inj1 (tgt l) (tgt r) . l) ||| (inj2 (tgt l) (tgt r) . r) where { type family BinaryCoproduct (k :: * -> * -> *) x y :: *; } inj1 :: HasBinaryCoproducts k => Obj k x -> Obj k y -> k x (BinaryCoproduct k x y) inj2 :: HasBinaryCoproducts k => Obj k x -> Obj k y -> k y (BinaryCoproduct k x y) (|||) :: HasBinaryCoproducts k => k x a -> k y a -> k (BinaryCoproduct k x y) a (+++) :: HasBinaryCoproducts k => k a1 b1 -> k a2 b2 -> k (BinaryCoproduct k a1 a2) (BinaryCoproduct k b1 b2) data CoproductFunctor (k :: * -> * -> *) CoproductFunctor :: CoproductFunctor data (:+:) p q [:+:] :: (Functor p, Functor q, Dom p ~ Dom q, Cod p ~ k, Cod q ~ k, HasBinaryCoproducts k) => p -> q -> p :+: q -- | A specialisation of the colimit adjunction to coproducts. coprodAdj :: HasBinaryCoproducts k => Adjunction k (k :**: k) (CoproductFunctor k) (DiagProd k) instance (Data.Category.Category j, Data.Category.Category k) => Data.Category.Functor.Functor (Data.Category.Limit.Diag j k) instance Data.Category.Limit.HasLimits j k => Data.Category.Functor.Functor (Data.Category.Limit.LimitFunctor j k) instance Data.Category.Limit.HasColimits j k => Data.Category.Functor.Functor (Data.Category.Limit.ColimitFunctor j k) instance Data.Category.Limit.HasTerminalObject k => Data.Category.Limit.HasLimits Data.Category.Void.Void k instance Data.Category.Limit.HasTerminalObject (->) instance Data.Category.Limit.HasTerminalObject Data.Category.Functor.Cat instance (Data.Category.Category c, Data.Category.Limit.HasTerminalObject d) => Data.Category.Limit.HasTerminalObject (Data.Category.NaturalTransformation.Nat c d) instance Data.Category.Limit.HasTerminalObject Data.Category.Unit.Unit instance (Data.Category.Limit.HasTerminalObject c1, Data.Category.Limit.HasTerminalObject c2) => Data.Category.Limit.HasTerminalObject (c1 Data.Category.Product.:**: c2) instance (Data.Category.Category c1, Data.Category.Limit.HasTerminalObject c2) => Data.Category.Limit.HasTerminalObject (c1 Data.Category.Coproduct.:>>: c2) instance Data.Category.Limit.HasInitialObject k => Data.Category.Limit.HasColimits Data.Category.Void.Void k instance Data.Category.Limit.HasInitialObject (->) instance Data.Category.Limit.HasInitialObject Data.Category.Functor.Cat instance (Data.Category.Category c, Data.Category.Limit.HasInitialObject d) => Data.Category.Limit.HasInitialObject (Data.Category.NaturalTransformation.Nat c d) instance (Data.Category.Limit.HasInitialObject c1, Data.Category.Limit.HasInitialObject c2) => Data.Category.Limit.HasInitialObject (c1 Data.Category.Product.:**: c2) instance Data.Category.Limit.HasInitialObject Data.Category.Unit.Unit instance (Data.Category.Limit.HasInitialObject c1, Data.Category.Category c2) => Data.Category.Limit.HasInitialObject (c1 Data.Category.Coproduct.:>>: c2) instance (Data.Category.Limit.HasLimits i k, Data.Category.Limit.HasLimits j k, Data.Category.Limit.HasBinaryProducts k) => Data.Category.Limit.HasLimits (i Data.Category.Coproduct.:++: j) k instance Data.Category.Limit.HasBinaryProducts (->) instance Data.Category.Limit.HasBinaryProducts Data.Category.Functor.Cat instance Data.Category.Limit.HasBinaryProducts Data.Category.Unit.Unit instance (Data.Category.Limit.HasBinaryProducts c1, Data.Category.Limit.HasBinaryProducts c2) => Data.Category.Limit.HasBinaryProducts (c1 Data.Category.Product.:**: c2) instance (Data.Category.Limit.HasBinaryProducts c1, Data.Category.Limit.HasBinaryProducts c2) => Data.Category.Limit.HasBinaryProducts (c1 Data.Category.Coproduct.:>>: c2) instance Data.Category.Limit.HasBinaryProducts k => Data.Category.Functor.Functor (Data.Category.Limit.ProductFunctor k) instance (Data.Category.Category (Data.Category.Functor.Dom p), Data.Category.Category (Data.Category.Functor.Cod p)) => Data.Category.Functor.Functor (p Data.Category.Limit.:*: q) instance (Data.Category.Category c, Data.Category.Limit.HasBinaryProducts d) => Data.Category.Limit.HasBinaryProducts (Data.Category.NaturalTransformation.Nat c d) instance (Data.Category.Limit.HasColimits i k, Data.Category.Limit.HasColimits j k, Data.Category.Limit.HasBinaryCoproducts k) => Data.Category.Limit.HasColimits (i Data.Category.Coproduct.:++: j) k instance Data.Category.Limit.HasBinaryCoproducts Data.Category.Functor.Cat instance Data.Category.Limit.HasBinaryCoproducts Data.Category.Unit.Unit instance (Data.Category.Limit.HasBinaryCoproducts c1, Data.Category.Limit.HasBinaryCoproducts c2) => Data.Category.Limit.HasBinaryCoproducts (c1 Data.Category.Product.:**: c2) instance (Data.Category.Limit.HasBinaryCoproducts c1, Data.Category.Limit.HasBinaryCoproducts c2) => Data.Category.Limit.HasBinaryCoproducts (c1 Data.Category.Coproduct.:>>: c2) instance Data.Category.Limit.HasBinaryCoproducts k => Data.Category.Functor.Functor (Data.Category.Limit.CoproductFunctor k) instance (Data.Category.Category (Data.Category.Functor.Dom p), Data.Category.Category (Data.Category.Functor.Cod p)) => Data.Category.Functor.Functor (p Data.Category.Limit.:+: q) instance (Data.Category.Category c, Data.Category.Limit.HasBinaryCoproducts d) => Data.Category.Limit.HasBinaryCoproducts (Data.Category.NaturalTransformation.Nat c d) instance Data.Category.Limit.HasInitialObject k => Data.Category.Limit.HasTerminalObject (Data.Category.Op k) instance Data.Category.Limit.HasTerminalObject k => Data.Category.Limit.HasInitialObject (Data.Category.Op k) instance Data.Category.Limit.HasBinaryCoproducts k => Data.Category.Limit.HasBinaryProducts (Data.Category.Op k) instance Data.Category.Limit.HasBinaryProducts k => Data.Category.Limit.HasBinaryCoproducts (Data.Category.Op k) instance Data.Category.Category k => Data.Category.Limit.HasLimits Data.Category.Unit.Unit k instance (Data.Category.Limit.HasInitialObject (i Data.Category.Coproduct.:>>: j), Data.Category.Category k) => Data.Category.Limit.HasLimits (i Data.Category.Coproduct.:>>: j) k instance Data.Category.Category k => Data.Category.Limit.HasColimits Data.Category.Unit.Unit k instance (Data.Category.Limit.HasTerminalObject (i Data.Category.Coproduct.:>>: j), Data.Category.Category k) => Data.Category.Limit.HasColimits (i Data.Category.Coproduct.:>>: j) k instance Data.Category.Limit.HasLimits (->) (->) instance Data.Category.Limit.HasColimits (->) (->) -- | Comma categories. module Data.Category.Comma data CommaO :: * -> * -> * -> * [CommaO] :: (Cod t ~ k, Cod s ~ k) => Obj (Dom t) a -> k (t :% a) (s :% b) -> Obj (Dom s) b -> CommaO t s (a, b) data (:/\:) :: * -> * -> * -> * -> * [CommaA] :: CommaO t s (a, b) -> Dom t a a' -> Dom s b b' -> CommaO t s (a', b') -> (t :/\: s) (a, b) (a', b') commaId :: CommaO t s (a, b) -> Obj (t :/\: s) (a, b) -- | The comma category T \downarrow S type ObjectsFUnder f a = ConstF f a :/\: f type ObjectsFOver f a = f :/\: ConstF f a type ObjectsUnder c a = Id c `ObjectsFUnder` a type ObjectsOver c a = Id c `ObjectsFOver` a initialUniversalComma :: forall u x c a a_. (Functor u, c ~ (u `ObjectsFUnder` x), HasInitialObject c, (a_, a) ~ InitialObject c) => u -> InitialUniversal x u a terminalUniversalComma :: forall u x c a a_. (Functor u, c ~ (u `ObjectsFOver` x), HasTerminalObject c, (a, a_) ~ TerminalObject c) => u -> TerminalUniversal x u a instance (Data.Category.Category (Data.Category.Functor.Dom t), Data.Category.Category (Data.Category.Functor.Dom s)) => Data.Category.Category (t Data.Category.Comma.:/\: s) module Data.Category.Monoidal -- | A monoidal category is a category with some kind of tensor product. A -- tensor product is a bifunctor, with a unit object. class (Functor f, Dom f ~ (Cod f :**: Cod f)) => TensorProduct f where type Unit f :: * where { type family Unit f :: *; } unitObject :: TensorProduct f => f -> Obj (Cod f) (Unit f) leftUnitor :: (TensorProduct f, Cod f ~ k) => f -> Obj k a -> k (f :% (Unit f, a)) a leftUnitorInv :: (TensorProduct f, Cod f ~ k) => f -> Obj k a -> k a (f :% (Unit f, a)) rightUnitor :: (TensorProduct f, Cod f ~ k) => f -> Obj k a -> k (f :% (a, Unit f)) a rightUnitorInv :: (TensorProduct f, Cod f ~ k) => f -> Obj k a -> k a (f :% (a, Unit f)) associator :: (TensorProduct f, Cod f ~ k) => f -> Obj k a -> Obj k b -> Obj k c -> k (f :% (f :% (a, b), c)) (f :% (a, f :% (b, c))) associatorInv :: (TensorProduct f, Cod f ~ k) => f -> Obj k a -> Obj k b -> Obj k c -> k (f :% (a, f :% (b, c))) (f :% (f :% (a, b), c)) -- | If a category has all products, then the product functor makes it a -- monoidal category, with the terminal object as unit. -- | If a category has all coproducts, then the coproduct functor makes it -- a monoidal category, with the initial object as unit. -- | Functor composition makes the category of endofunctors monoidal, with -- the identity functor as unit. -- | MonoidObject f a defines a monoid a in a monoidal -- category with tensor product f. data MonoidObject f a MonoidObject :: Cod f (Unit f) a -> Cod f ((f :% (a, a))) a -> MonoidObject f a [unit] :: MonoidObject f a -> Cod f (Unit f) a [multiply] :: MonoidObject f a -> Cod f ((f :% (a, a))) a trivialMonoid :: TensorProduct f => f -> MonoidObject f (Unit f) coproductMonoid :: (HasInitialObject k, HasBinaryCoproducts k) => Obj k a -> MonoidObject (CoproductFunctor k) a -- | ComonoidObject f a defines a comonoid a in a -- comonoidal category with tensor product f. data ComonoidObject f a ComonoidObject :: Cod f a (Unit f) -> Cod f a (f :% (a, a)) -> ComonoidObject f a [counit] :: ComonoidObject f a -> Cod f a (Unit f) [comultiply] :: ComonoidObject f a -> Cod f a (f :% (a, a)) trivialComonoid :: TensorProduct f => f -> ComonoidObject f (Unit f) productComonoid :: (HasTerminalObject k, HasBinaryProducts k) => Obj k a -> ComonoidObject (ProductFunctor k) a data MonoidAsCategory f m a b [MonoidValue] :: (TensorProduct f, Dom f ~ (k :**: k), Cod f ~ k) => f -> MonoidObject f m -> k (Unit f) m -> MonoidAsCategory f m m m -- | A monoid as a category with one object. -- | A monad is a monoid in the category of endofunctors. type Monad f = MonoidObject (EndoFunctorCompose (Dom f)) f mkMonad :: (Functor f, Dom f ~ k, Cod f ~ k) => f -> (forall a. Obj k a -> Component (Id k) f a) -> (forall a. Obj k a -> Component (f :.: f) f a) -> Monad f monadFunctor :: Monad f -> f idMonad :: Category k => Monad (Id k) -- | A comonad is a comonoid in the category of endofunctors. type Comonad f = ComonoidObject (EndoFunctorCompose (Dom f)) f mkComonad :: (Functor f, Dom f ~ k, Cod f ~ k) => f -> (forall a. Obj k a -> Component f (Id k) a) -> (forall a. Obj k a -> Component f (f :.: f) a) -> Comonad f idComonad :: Category k => Comonad (Id k) -- | Every adjunction gives rise to an associated monad. adjunctionMonad :: Adjunction c d f g -> Monad (g :.: f) -- | Every adjunction gives rise to an associated monad transformer. adjunctionMonadT :: (Dom m ~ c) => Adjunction c d f g -> Monad m -> Monad ((g :.: m) :.: f) -- | Every adjunction gives rise to an associated comonad. adjunctionComonad :: Adjunction c d f g -> Comonad (f :.: g) -- | Every adjunction gives rise to an associated comonad transformer. adjunctionComonadT :: (Dom w ~ d) => Adjunction c d f g -> Comonad w -> Comonad ((f :.: w) :.: g) instance (Data.Category.Limit.HasTerminalObject k, Data.Category.Limit.HasBinaryProducts k) => Data.Category.Monoidal.TensorProduct (Data.Category.Limit.ProductFunctor k) instance (Data.Category.Limit.HasInitialObject k, Data.Category.Limit.HasBinaryCoproducts k) => Data.Category.Monoidal.TensorProduct (Data.Category.Limit.CoproductFunctor k) instance Data.Category.Category k => Data.Category.Monoidal.TensorProduct (Data.Category.NaturalTransformation.EndoFunctorCompose k) instance Data.Category.Category (Data.Category.Monoidal.MonoidAsCategory f m) -- | The cube category. module Data.Category.Cube data Z data S n data Sign M :: Sign P :: Sign data Cube :: * -> * -> * [Z] :: Cube Z Z [S] :: Cube x y -> Cube (S x) (S y) [Y] :: Sign -> Cube x y -> Cube x (S y) [X] :: Cube x y -> Cube (S x) y data Sign0 SM :: Sign0 S0 :: Sign0 SP :: Sign0 data ACube :: * -> * [Nil] :: ACube Z [Cons] :: Sign0 -> ACube n -> ACube (S n) data Forget Forget :: Forget -- | Turn Cube x y arrows into ACube x -> ACube y -- functions. data Add Add :: Add -- | Ordinal addition is a bifuntor, it concattenates the maps as it were. instance Data.Category.Category Data.Category.Cube.Cube instance Data.Category.Limit.HasTerminalObject Data.Category.Cube.Cube instance Data.Category.Functor.Functor Data.Category.Cube.Forget instance Data.Category.Functor.Functor Data.Category.Cube.Add instance Data.Category.Monoidal.TensorProduct Data.Category.Cube.Add -- | Dialg(F,G), the category of (F,G)-dialgebras and (F,G)-homomorphisms. module Data.Category.Dialg -- | Objects of Dialg(F,G) are (F,G)-dialgebras. data Dialgebra f g a [Dialgebra] :: (Category c, Category d, Dom f ~ c, Dom g ~ c, Cod f ~ d, Cod g ~ d, Functor f, Functor g) => Obj c a -> d (f :% a) (g :% a) -> Dialgebra f g a -- | Arrows of Dialg(F,G) are (F,G)-homomorphisms. data Dialg f g a b [DialgA] :: (Category c, Category d, Dom f ~ c, Dom g ~ c, Cod f ~ d, Cod g ~ d, Functor f, Functor g) => Dialgebra f g a -> Dialgebra f g b -> c a b -> Dialg f g a b dialgId :: Dialgebra f g a -> Obj (Dialg f g) a dialgebra :: Obj (Dialg f g) a -> Dialgebra f g a -- | The category of (F,G)-dialgebras. type Alg f = Dialg f (Id (Dom f)) type Algebra f a = Dialgebra f (Id (Dom f)) a type Coalg f = Dialg (Id (Dom f)) f type Coalgebra f a = Dialgebra (Id (Dom f)) f a -- | The initial F-algebra is the initial object in the category of -- F-algebras. type InitialFAlgebra f = InitialObject (Alg f) -- | The terminal F-coalgebra is the terminal object in the category of -- F-coalgebras. type TerminalFAlgebra f = TerminalObject (Coalg f) -- | A catamorphism of an F-algebra is the arrow to it from the initial -- F-algebra. type Cata f a = Algebra f a -> Alg f (InitialFAlgebra f) a -- | A anamorphism of an F-coalgebra is the arrow from it to the terminal -- F-coalgebra. type Ana f a = Coalgebra f a -> Coalg f a (TerminalFAlgebra f) data NatNum Z :: () -> NatNum S :: NatNum -> NatNum primRec :: (() -> t) -> (t -> t) -> NatNum -> t -- | The category for defining the natural numbers and primitive recursion -- can be described as Dialg(F,G), with -- F(A)=<1,A> and G(A)=<A,A>. data FreeAlg m FreeAlg :: (Monad m) -> FreeAlg m -- | FreeAlg M takes x to the free algebra (M x, -- mu_x) of the monad M. data ForgetAlg m ForgetAlg :: ForgetAlg m -- | ForgetAlg m is the forgetful functor for Alg m. eilenbergMooreAdj :: (Functor m, Dom m ~ k, Cod m ~ k) => Monad m -> Adjunction (Alg m) k (FreeAlg m) (ForgetAlg m) instance Data.Category.Category (Data.Category.Dialg.Dialg f g) instance Data.Category.Limit.HasInitialObject (Data.Category.Dialg.Dialg (Data.Category.Functor.Tuple1 (->) (->) ()) (Data.Category.Functor.DiagProd (->))) instance (Data.Category.Functor.Functor m, Data.Category.Functor.Dom m ~ k, Data.Category.Functor.Cod m ~ k) => Data.Category.Functor.Functor (Data.Category.Dialg.FreeAlg m) instance (Data.Category.Functor.Functor m, Data.Category.Functor.Dom m ~ k, Data.Category.Functor.Cod m ~ k) => Data.Category.Functor.Functor (Data.Category.Dialg.ForgetAlg m) -- | This is an attempt at the Kleisli category, and the construction of an -- adjunction for each monad. module Data.Category.Kleisli data Kleisli m a b [Kleisli] :: (Functor m, Dom m ~ k, Cod m ~ k) => Monad m -> Obj k b -> k a (m :% b) -> Kleisli m a b kleisliId :: (Functor m, Dom m ~ k, Cod m ~ k) => Monad m -> Obj k a -> Kleisli m a a -- | The category of Kleisli arrows. data KleisliAdjF m KleisliAdjF :: (Monad m) -> KleisliAdjF m data KleisliAdjG m KleisliAdjG :: (Monad m) -> KleisliAdjG m kleisliAdj :: (Functor m, Dom m ~ k, Cod m ~ k) => Monad m -> Adjunction (Kleisli m) k (KleisliAdjF m) (KleisliAdjG m) instance Data.Category.Category (Data.Category.Kleisli.Kleisli m) instance (Data.Category.Functor.Functor m, Data.Category.Functor.Dom m ~ k, Data.Category.Functor.Cod m ~ k) => Data.Category.Functor.Functor (Data.Category.Kleisli.KleisliAdjF m) instance (Data.Category.Functor.Functor m, Data.Category.Functor.Dom m ~ k, Data.Category.Functor.Cod m ~ k) => Data.Category.Functor.Functor (Data.Category.Kleisli.KleisliAdjG m) -- | The (augmented) simplex category. module Data.Category.Simplex data Simplex :: * -> * -> * [Z] :: Simplex Z Z [Y] :: Simplex x y -> Simplex x (S y) [X] :: Simplex x (S y) -> Simplex (S x) (S y) data Z data S n suc :: Obj Simplex n -> Obj Simplex (S n) data Forget Forget :: Forget data Fin :: * -> * [Fz] :: Fin (S n) [Fs] :: Fin n -> Fin (S n) data Add Add :: Add -- | The maps 0 -> 1 and 2 -> 1 form a monoid, -- which is universal, c.f. Replicate. universalMonoid :: MonoidObject Add (S Z) data Replicate f a Replicate :: f -> (MonoidObject f a) -> Replicate f a instance Data.Category.Category Data.Category.Simplex.Simplex instance Data.Category.Limit.HasInitialObject Data.Category.Simplex.Simplex instance Data.Category.Limit.HasTerminalObject Data.Category.Simplex.Simplex instance Data.Category.Functor.Functor Data.Category.Simplex.Forget instance Data.Category.Functor.Functor Data.Category.Simplex.Add instance Data.Category.Monoidal.TensorProduct Data.Category.Simplex.Add instance Data.Category.Monoidal.TensorProduct f => Data.Category.Functor.Functor (Data.Category.Simplex.Replicate f a) module Data.Category.Yoneda type YonedaEmbedding k = Postcompose (Hom k) (Op k) :.: (Postcompose (Swap k (Op k)) (Op k) :.: Tuple k (Op k)) -- | The Yoneda embedding functor, C -> Set^(C^op). yonedaEmbedding :: Category k => YonedaEmbedding k data Yoneda (k :: * -> * -> *) f Yoneda :: Yoneda f -- | Yoneda converts a functor f into a natural -- transformation from the hom functor to f. -- | fromYoneda and toYoneda are together the isomophism from -- the Yoneda lemma. fromYoneda :: (Category k, Functor f, Dom f ~ Op k, Cod f ~ (->)) => f -> Nat (Op k) (->) (Yoneda k f) f toYoneda :: (Category k, Functor f, Dom f ~ Op k, Cod f ~ (->)) => f -> Nat (Op k) (->) f (Yoneda k f) instance (Data.Category.Category k, Data.Category.Functor.Functor f, Data.Category.Functor.Dom f ~ Data.Category.Op k, Data.Category.Functor.Cod f ~ (->)) => Data.Category.Functor.Functor (Data.Category.Yoneda.Yoneda k f) module Data.Category.CartesianClosed -- | A category is cartesian closed if it has all products and exponentials -- for all objects. class (HasTerminalObject k, HasBinaryProducts k) => CartesianClosed k where type Exponential k y z :: * where { type family Exponential k y z :: *; } apply :: CartesianClosed k => Obj k y -> Obj k z -> k (BinaryProduct k (Exponential k y z) y) z tuple :: CartesianClosed k => Obj k y -> Obj k z -> k z (Exponential k y (BinaryProduct k z y)) (^^^) :: CartesianClosed k => k z1 z2 -> k y2 y1 -> k (Exponential k y1 z1) (Exponential k y2 z2) data ExpFunctor (k :: * -> * -> *) ExpFunctor :: ExpFunctor -- | The exponential as a bifunctor. -- | Exponentials in Hask are functions. -- | Exponentials in Cat are the functor categories. type PShExponential k y z = (Presheaves k :-*: z) :.: Opposite ((ProductFunctor (Presheaves k) :.: Tuple2 (Presheaves k) (Presheaves k) y) :.: YonedaEmbedding k) pshExponential :: Category k => Obj (Presheaves k) y -> Obj (Presheaves k) z -> PShExponential k y z -- | The category of presheaves on a category C is cartesian -- closed for any C. -- | The product functor is left adjoint the the exponential functor. curryAdj :: CartesianClosed k => Obj k y -> Adjunction k k (ProductFunctor k :.: Tuple2 k k y) (ExpFunctor k :.: Tuple1 (Op k) k y) -- | From the adjunction between the product functor and the exponential -- functor we get the curry and uncurry functions, generalized to any -- cartesian closed category. curry :: CartesianClosed k => Obj k x -> Obj k y -> Obj k z -> k (BinaryProduct k x y) z -> k x (Exponential k y z) uncurry :: CartesianClosed k => Obj k x -> Obj k y -> Obj k z -> k x (Exponential k y z) -> k (BinaryProduct k x y) z -- | From every adjunction we get a monad, in this case the State monad. type State k s a = Exponential k s (BinaryProduct k a s) stateMonadReturn :: CartesianClosed k => Obj k s -> Obj k a -> k a (State k s a) stateMonadJoin :: CartesianClosed k => Obj k s -> Obj k a -> k (State k s (State k s a)) (State k s a) type Context k s a = BinaryProduct k (Exponential k s a) s contextComonadExtract :: CartesianClosed k => Obj k s -> Obj k a -> k (Context k s a) a contextComonadDuplicate :: CartesianClosed k => Obj k s -> Obj k a -> k (Context k s a) (Context k s (Context k s a)) instance Data.Category.CartesianClosed.CartesianClosed k => Data.Category.Functor.Functor (Data.Category.CartesianClosed.ExpFunctor k) instance Data.Category.CartesianClosed.CartesianClosed (->) instance Data.Category.CartesianClosed.CartesianClosed Data.Category.Functor.Cat instance Data.Category.Category k => Data.Category.CartesianClosed.CartesianClosed (Data.Category.NaturalTransformation.Presheaves k) -- | 2, or the Boolean category. It contains 2 objects, one for true -- and one for false. It contains 3 arrows, 2 identity arrows and one -- from false to true. module Data.Category.Boolean data Fls data Tru data Boolean a b [Fls] :: Boolean Fls Fls [F2T] :: Boolean Fls Tru [Tru] :: Boolean Tru Tru -- | Boolean is the category with true and false as objects, and -- an arrow from false to true. -- | False is the initial object in the Boolean category. -- | True is the terminal object in the Boolean category. -- | Conjunction is the binary product in the Boolean category. -- | Disjunction is the binary coproduct in the Boolean category. -- | Implication makes the Boolean category cartesian closed. trueProductMonoid :: MonoidObject (ProductFunctor Boolean) Tru falseCoproductComonoid :: ComonoidObject (CoproductFunctor Boolean) Fls trueProductComonoid :: ComonoidObject (ProductFunctor Boolean) Tru falseCoproductMonoid :: MonoidObject (CoproductFunctor Boolean) Fls trueCoproductMonoid :: MonoidObject (CoproductFunctor Boolean) Tru falseProductComonoid :: ComonoidObject (ProductFunctor Boolean) Fls instance Data.Category.Category Data.Category.Boolean.Boolean instance Data.Category.Limit.HasInitialObject Data.Category.Boolean.Boolean instance Data.Category.Limit.HasTerminalObject Data.Category.Boolean.Boolean instance Data.Category.Limit.HasBinaryProducts Data.Category.Boolean.Boolean instance Data.Category.Limit.HasBinaryCoproducts Data.Category.Boolean.Boolean instance Data.Category.CartesianClosed.CartesianClosed Data.Category.Boolean.Boolean module Data.Category.Fix newtype Fix f a b Fix :: (f (Fix f) a b) -> Fix f a b -- | Fix f is the fixed point category for a category -- combinator f. -- | Fix f inherits its (co)limits from f (Fix f). -- | Fix f inherits its (co)limits from f (Fix f). -- | Fix f inherits its (co)limits from f (Fix f). -- | Fix f inherits its (co)limits from f (Fix f). -- | Fix f inherits its exponentials from f (Fix f). data Wrap (f :: (* -> * -> *) -> * -> * -> *) Wrap :: Wrap -- | The Wrap functor wraps Fix around f (Fix f). -- | Take the Omega category, add a new disctinct object, and an -- arrow from that object to every object in Omega, and you get -- Omega again. type Omega = Fix ((:>>:) Unit) instance Data.Category.Category (f (Data.Category.Fix.Fix f)) => Data.Category.Category (Data.Category.Fix.Fix f) instance Data.Category.Limit.HasInitialObject (f (Data.Category.Fix.Fix f)) => Data.Category.Limit.HasInitialObject (Data.Category.Fix.Fix f) instance Data.Category.Limit.HasTerminalObject (f (Data.Category.Fix.Fix f)) => Data.Category.Limit.HasTerminalObject (Data.Category.Fix.Fix f) instance Data.Category.Limit.HasBinaryProducts (f (Data.Category.Fix.Fix f)) => Data.Category.Limit.HasBinaryProducts (Data.Category.Fix.Fix f) instance Data.Category.Limit.HasBinaryCoproducts (f (Data.Category.Fix.Fix f)) => Data.Category.Limit.HasBinaryCoproducts (Data.Category.Fix.Fix f) instance Data.Category.CartesianClosed.CartesianClosed (f (Data.Category.Fix.Fix f)) => Data.Category.CartesianClosed.CartesianClosed (Data.Category.Fix.Fix f) instance Data.Category.Category (f (Data.Category.Fix.Fix f)) => Data.Category.Functor.Functor (Data.Category.Fix.Wrap f) module Data.Category.NNO class HasTerminalObject k => HasNaturalNumberObject k where type NaturalNumberObject k :: * where { type family NaturalNumberObject k :: *; } zero :: HasNaturalNumberObject k => k (TerminalObject k) (NaturalNumberObject k) succ :: HasNaturalNumberObject k => k (NaturalNumberObject k) (NaturalNumberObject k) primRec :: HasNaturalNumberObject k => k (TerminalObject k) a -> k a a -> k (NaturalNumberObject k) a data NatNum Z :: NatNum S :: NatNum -> NatNum type Nat = Fix ((:++:) Unit) data PrimRec z s PrimRec :: z -> s -> PrimRec z s instance Data.Category.NNO.HasNaturalNumberObject (->) instance Data.Category.NNO.HasNaturalNumberObject Data.Category.Functor.Cat instance (Data.Category.Functor.Functor z, Data.Category.Functor.Functor s, Data.Category.Functor.Dom z ~ Data.Category.Unit.Unit, Data.Category.Functor.Cod z ~ Data.Category.Functor.Dom s, Data.Category.Functor.Dom s ~ Data.Category.Functor.Cod s) => Data.Category.Functor.Functor (Data.Category.NNO.PrimRec z s)