{-# OPTIONS --type-in-type #-}
open import NeilPrelude
open import List
open import Bool
module MonadPlus (M : Set → Set)
(_>>=_ : {A B : Set} → M A → (A → M B) → M B)
(return : {A : Set} → A → M A)
(plus : {A : Set} → M A → M A → M A)
(zero : {A : Set} → M A)
where
import Monad
open Monad M _>>=_ return public
mplus : {A : Set} → M A → M A → M A
mplus = plus
mzero : {A : Set} → M A
mzero = zero
msum : {A : Set} → List (M A) → M A
msum = foldl mplus mzero
mfilter : {A : Set} → (A → Bool) → M A → M A
mfilter p ma = ma >>= λ a → if p a then return a else mzero
guard : Bool → M Unit
guard false = mzero
guard true = return unit