packages feed

data-category-0.0.1: Data/Category.hs

{-# LANGUAGE TypeOperators, TypeFamilies, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances, RankNTypes #-}
module Data.Category where

import Prelude hiding ((.), id, ($))



class CategoryO (~>) a where
  id :: a ~> a
  
class (CategoryO (~>) a, CategoryO (~>) b, CategoryO (~>) c) => CategoryA (~>) a b c where
  (.) :: b ~> c -> a ~> b -> a ~> c

class (CategoryO (~>) a, CategoryO (~>) b) => Apply (~>) a b where
  -- Would have liked to use ($) here, but that causes GHC to crash.
  -- http://hackage.haskell.org/trac/ghc/ticket/3297
  ($$) :: a ~> b -> a -> b
  

type family F ftag a :: *
type family Dom ftag :: * -> * -> *
type family Cod ftag :: * -> * -> *

class (CategoryO (Dom ftag) a, CategoryO (Dom ftag) b) 
  => FunctorA ftag a b where
  (%) :: ftag -> Dom ftag a b -> Cod ftag (F ftag a) (F ftag b)

class (CategoryO (Dom ftag) a, CategoryO (Dom ftag) b) 
  => ContraFunctorA ftag a b where
  (-%) :: ftag -> Dom ftag a b -> Cod ftag (F ftag b) (F ftag a)


-- |The identity functor on (~>)
data Id ((~>) :: * -> * -> *) = Id
type instance F (Id (~>)) a = a
type instance Dom (Id (~>)) = (~>)
type instance Cod (Id (~>)) = (~>)
instance (CategoryO (~>) a, CategoryO (~>) b) => FunctorA (Id (~>)) a b where
  Id % f = f

-- |The composition of two functors.
data (g :.: h) = g :.: h
type instance F (g :.: h) a = F g (F h a)
type instance Dom (g :.: h) = Dom h
type instance Cod (g :.: h) = Cod g
instance (FunctorA g (F h a) (F h b), FunctorA h a b, Cod h ~ Dom g) => FunctorA (g :.: h) a b where
   (g :.: h) % f = g % (h % f)

-- |The constant functor.
data Const (c1 :: * -> * -> *) (c2 :: * -> * -> *) x = Const
type instance F (Const c1 c2 x) a = x
type instance Dom (Const c1 c2 x) = c1
type instance Cod (Const c1 c2 x) = c2
instance (CategoryO c1 a, CategoryO c1 b, CategoryO c2 x) => FunctorA (Const c1 c2 x) a b where
  Const % f = id
  
-- |The covariant functor Hom(X,--)
data (x :*-: ((~>) :: * -> * -> *)) = HomX_
type instance F (x :*-: (~>)) a = x ~> a
type instance Dom (x :*-: (~>)) = (~>)
type instance Cod (x :*-: (~>)) = (->)
instance (CategoryO (~>) a, CategoryO (~>) b, CategoryA (~>) x a b) => FunctorA (x :*-: (~>)) a b where
  HomX_ % f = (f .)

-- |The contravariant functor Hom(--,X)
data (((~>) :: * -> * -> *) :-*: x) = Hom_X
type instance F ((~>) :-*: x) a = a ~> x
type instance Dom ((~>) :-*: x) = (~>)
type instance Cod ((~>) :-*: x) = (->)
instance (CategoryO (~>) a, CategoryO (~>) b, CategoryA (~>) a b x) => ContraFunctorA ((~>) :-*: x) a b where
  Hom_X -% f = (. f)