module stlc.monad where

open import stlc.type public

data Monad {A : Type} : Type  Set where
  exception :  {E}  Monad (A + E)
  state :  {S}  Monad (S  (S × A))
  nondeterminism : Monad (list A)
  continuation :  {R}  Monad ((A  R)  R)

data SameMonad :  {A B TA TB}  Monad {A} TA  Monad {B} TB  Set where
  exception :  {A B E}  SameMonad (exception {A} {E}) (exception {B} {E})
  state :  {A B S}  SameMonad (state {A} {S}) (state {B} {S})
  nondeterminism :  {A B}  SameMonad (nondeterminism {A}) (nondeterminism {B})
  continuation :  {A B R}  SameMonad (continuation {A} {R}) (continuation {B} {R})

sameMonadTrans :  {A B C TA TB TC} {ma : Monad {A} TA} {mb : Monad {B} TB} {mc : Monad {C} TC}  SameMonad ma mb  SameMonad mb mc  SameMonad ma mc
sameMonadTrans exception exception = exception
sameMonadTrans state state = state
sameMonadTrans nondeterminism nondeterminism = nondeterminism
sameMonadTrans continuation continuation = continuation

getMonadType :  {A TA}  Monad {A} TA  Type
getMonadType {TA = TA} m = TA