a data type can be an instance of Category only if it has kind * -> * -> *. It must have 2 type parameters so that you could have types like 'cat a a'.
import Prelude hiding (id, (.))
import Control.Category
import Data.Monoid
newtype Op c a b = Op (c b a)
instance Category c => Category (Op c) where
id = Op id
(Op x) . (Op y) = Op (y . x)
-- A category whose morphisms are bijections between types.
data Iso a b = Iso (a -> b) (b -> a)
instance Category Iso where
id = Iso id id
(Iso f1 g1) . (Iso f2 g2) = Iso (f1 . f2) (g2 . g1)
-- A product of two categories forms a new category:
data ProductCat c d a b = ProductCat (c a b) (d a b)
instance (Category c, Category d) => Category (ProductCat c d) where
id = ProductCat id id
(ProductCat f g) . (ProductCat f' g') = ProductCat (f . f') (g . g')
-- A category constructed from a monoid. It
-- ignores the types. Any morphism in this category
-- is simply an element of the given monoid.
newtype MonoidCat m a b = MonoidCat m
instance (Monoid m) => Category (MonoidCat m) where
id = MonoidCat mempty
MonoidCat x . MonoidCat y = MonoidCat (x `mappend` y)
Many interesting categories can be constructed from various monads using Kleisli. For example, Kleisli Maybe is the category of partial functions.
Best regards,
Petr