{-# OPTIONS --type-in-type #-}
open import NeilPrelude
module Monad (M : Set → Set)
(_>>='_ : {A B : Set} → M A → (A → M B) → M B)
(ret : {A : Set} → A → M A)
where
infixl 4 _>>=_ _>>_
_>>=_ : {A B : Set} → M A → (A → M B) → M B
_>>=_ = _>>='_
_=<<_ : {A B : Set} → (A → M B) → M A → M B
_=<<_ = flip _>>=_
return : {A : Set} → A → M A
return = ret
ap : {A B : Set} → M (A → B) → M A → M B
ap mf ma = mf >>= λ f → ma >>= return ∘ f
liftM : {A B : Set} → (A → B) → M A → M B
liftM f = ap (return f)
join : {A : Set} → M (M A) → M A
join ma = ma >>= id
_>>_ : {A B : Set} → M A → M B → M B
ma >> mb = ma >>= const mb
_<<_ : {A B : Set} → M B → M A → M B
_<<_ = flip _>>_
import Applicative
open Applicative M liftM return ap public