module Data.Semigroupoid
( Semigroupoid(..)
, WrappedCategory(..)
, Semi(..)
) where
import Control.Arrow
import Data.Functor.Bind
import Data.Semigroup
import Control.Category
import Prelude hiding (id, (.))
#ifdef MIN_VERSION_contravariant
import Data.Functor.Contravariant
#endif
#ifdef MIN_VERSION_comonad
import Data.Functor.Extend
import Control.Comonad
#endif
class Semigroupoid c where
o :: c j k -> c i j -> c i k
instance Semigroupoid (->) where
o = (.)
instance Semigroupoid (,) where
o (_,k) (i,_) = (i,k)
instance Bind m => Semigroupoid (Kleisli m) where
Kleisli g `o` Kleisli f = Kleisli $ \a -> f a >>- g
#ifdef MIN_VERSION_comonad
instance Extend w => Semigroupoid (Cokleisli w) where
Cokleisli f `o` Cokleisli g = Cokleisli $ f . extended g
#endif
#ifdef MIN_VERSION_contravariant
instance Semigroupoid Op where
Op f `o` Op g = Op (g `o` f)
#endif
newtype WrappedCategory k a b = WrapCategory { unwrapCategory :: k a b }
instance Category k => Semigroupoid (WrappedCategory k) where
WrapCategory f `o` WrapCategory g = WrapCategory (f . g)
instance Category k => Category (WrappedCategory k) where
id = WrapCategory id
WrapCategory f . WrapCategory g = WrapCategory (f . g)
newtype Semi m a b = Semi { getSemi :: m }
instance Semigroup m => Semigroupoid (Semi m) where
Semi m `o` Semi n = Semi (m <> n)
instance Monoid m => Category (Semi m) where
id = Semi mempty
Semi m . Semi n = Semi (m `mappend` n)