ix-0.1.1.0: src/Control/Categorical/Monad/Indexed.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE TypeOperators #-}
module Control.Categorical.Monad.Indexed (Monad (..), (<=<), (>=>), Comonad (..), (=<=), (=>=)) where
import Data.Function (flip)
import Control.Categorical.Functor
import Control.Category.Dual
infixr 1 >=>, <=<, =>=, =<=
class (∀ i j . Endofunctor s (m i j)) => Monad s m where
unit :: a `s` m k k a
join :: m i j (m j k a) `s` m i k a
join = bind id
bind :: a `s` m j k b -> m i j a `s` m i k b
bind f = join . map f
(<=<) :: Monad s m => b `s` m j k c -> a `s` m i j b -> a `s` m i k c
f <=< g = bind f . bind g . unit
(>=>) :: Monad s m => a `s` m i j b -> b `s` m j k c -> a `s` m i k c
(>=>) = flip (<=<)
instance Comonad s f => Monad (Dual s) f where
unit = Dual counit
join = Dual cut
instance (Category s, Comonad (NT s) f) => Monad (NT (Dual s)) f where
unit = NT (Dual (nt counit))
join = NT (Dual (nt cut))
class (∀ i j . Endofunctor s (ɯ i j)) => Comonad s ɯ where
counit :: ɯ k k a `s` a
cut :: ɯ i k a `s` ɯ i j (ɯ j k a)
cut = cobind id
cobind :: ɯ j k a `s` b -> ɯ i k a `s` ɯ i j b
cobind f = map f . cut
(=<=) :: Comonad s ɯ => ɯ i j b `s` c -> ɯ j k a `s` b -> ɯ i k a `s` c
f =<= g = counit . cobind f . cobind g
(=>=) :: Comonad s ɯ => ɯ j k a `s` b -> ɯ i j b `s` c -> ɯ i k a `s` c
(=>=) = flip (=<=)