module Monad where import qualified Prelude as P import Data.Constraint import Data.Proxy import Data.Tagged import Category import Functor import NatTr class EndoFunctorOf t c => Monad t (c :: o -> o -> *) | t -> c where nu :: NatTr c c (IdentityF c) t mu :: NatTr c c (Comp ('KProxy :: KProxy o) t t) t data MonadMorph c t s where MonadMorph :: (Monad t c, Monad s c) => NatTr c c t s -> MonadMorph c t s instance Category c => Category (MonadMorph c) where type Object (MonadMorph c) t = Monad t c id = MonadMorph id MonadMorph f . MonadMorph g = MonadMorph (f . g) observeObjects (MonadMorph _) = Dict data ForgetM c where ForgetM :: Category c => ForgetM c instance Category c => Functor (ForgetM c) ('KProxy :: KProxy (* -> *)) where type Domain (ForgetM c) = MonadMorph c type Codomain (ForgetM c) = NatTr c c type FMap (ForgetM c) (t :: *) = t morphMap = Tagged (\(MonadMorph t) -> t) instance (P.Functor m, P.Monad m) => Monad (Ftag m) (->) where nu = NatTr (Tagged P.return) mu = NatTr (Tagged (P.>>= id))