module TypeClass data Monad : (U -> U) -> U where MkMonad : { M : U -> U } -> (bind : {A B : U} -> (M A) -> (A -> M B) -> M B) -> (pure : {A : U} -> A -> M A) -> Monad M data Maybe : U -> U where Just : {A : U} -> A -> Maybe A Nothing : {A : U} -> Maybe A data Either : U -> U -> U where Left : {A B : U} -> A -> Either A B Right : {A B : U} -> B -> Either A B bindEither : {A B C : U} -> (Either A B) -> (B -> Either A C) -> Either A C bindEither (Left a) amb = Left a bindEither (Right b) amb = amb b EitherMonad : {A : U} -> Monad (Either A) EitherMonad = MkMonad {Either A} bindEither Right bindMaybe : {A B : U} -> Maybe A -> (A -> Maybe B) -> Maybe B bindMaybe Nothing amb = Nothing bindMaybe (Just a) amb = amb a MaybeMonad : Monad Maybe MaybeMonad = MkMonad bindMaybe Just _>>=_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> (m a) -> (a -> m b) -> m b _>>=_ {a} {b} {m} {{MkMonad bind' _}} ma amb = bind' {a} {b} ma amb pure : {a : U} {m : U -> U} {{_ : Monad m}} -> a -> m a pure {_} {_} {{MkMonad _ pure'}} a = pure' a infixl 1 _>>=_ _>>_ _>>_ : {a b : U} -> {m : U -> U} -> {{x : Monad m}} -> m a -> m b -> m b ma >> mb = mb ptype Int test : Maybe Int test = pure 10 foo : Int -> Maybe Int foo x = Just 42 >> Just x >>= (\ x => pure 10) bar : Int -> Maybe Int bar x = do let y = x z <- Just x pure z