module Category where import qualified Prelude as P import GHC.Prim import Data.Constraint -- |The class of categories @m@ with objects of kind @k@ which satisfy the -- constraint @Object m@. For any objects @a@ and @b@, the type @m a b@ is the -- type of morphisms with domain @a@ and codomain @b@. class Category (m :: k -> k -> *) where -- |The set of objects. type Object m (a :: k) :: Constraint -- |The Identity operator. id :: Object m a => m a a -- |The Composition operator. (.) :: m b c -> m a b -> m a c -- |Morphisms are arrows between objects. observeObjects :: m a b -> Dict (Object m a, Object m b) -- |The category Hask of functions between types. instance Category (->) where type Object (->) a = () id = P.id observeObjects = P.const Dict (.) = (P..) -- |The category of entailment from 'constraints' instance Category (:-) where type Object (:-) a = () id = refl observeObjects = P.const Dict (.) = trans -- |Dual categories newtype Op c a b = Op {unOp :: c b a} instance Category c => Category (Op c) where id = Op id (Op f) . (Op g) = Op (g . f) type Object (Op c) a = Object c a observeObjects (Op c) = case observeObjects c of Dict -> Dict