module Control.Category where

{- |

A class for categories. Instances of 'Category' should satisfy the
following laws:

> id . p  ==  p
> p . id  ==  p
> (p . q) . r  ==  p . (q . r)

-}

infixr 9 .
class Category (~>) where
    id  :: a ~> a                           -- ^ the identity morphism
    (.) :: b ~> c  ->  a ~> b  ->  a ~> c   -- ^ morphism composition

{-# RULES
"identity/left"  forall p .
                   id . p = p
"identity/right" forall p .
                   p . id = p
"association"    forall p q r .
                   (p . q) . r = p . (q . r)
 #-}

instance Category Hask where
    id x = x
    (f . g) x = f (g x)

infixr 1 <<<
-- | Right-to-left composition
(<<<) :: Category (~>) => b ~> c  ->  a ~> b  ->  a ~> c
(<<<) = (.)

infixr 1 >>>
-- | Left-to-right composition
(>>>) :: Category (~>) => a ~> b  ->  b ~> c  ->  a ~> c
f >>> g = g . f

result :: Category (~>) => b ~> c  ->  a ~> b  ->  a ~> c
result = (.)

result2 :: Category (~>) => c ~> d  ->  (a  ->  b ~> c)  ->  (a  ->  b ~> d)
result2 = result . result

result3 :: Category (~>) =>
           d ~> e  ->  (a  ->  b  ->  c ~> d)  ->  (a  ->  b  ->  c ~> e)
result3 = result . result2

result4 :: Category (~>) =>
           e ~> f  ->  (a  ->  b  ->  c  ->  d ~> e)  ->
           (a  ->  b  ->  c  ->  d ~> f)
result4 = result . result3

result5 :: Category (~>) =>
           f ~> g  ->  (a  ->  b  ->  c  ->  d  ->  e ~> f)  ->
           (a  ->  b  ->  c  ->  d  ->  e ~> g)
result5 = result . result4

type Hask = (->)
