------------------------------------------------------------------------ -- The Agda standard library -- -- Monads ------------------------------------------------------------------------ -- Note that currently the monad laws are not included here. {-# OPTIONS --cubical-compatible --safe #-} module Effect.Monad where open import Data.Bool.Base using (Bool; true; false; not) open import Data.Unit.Polymorphic.Base using (⊤) open import Effect.Choice open import Effect.Empty open import Effect.Applicative open import Function.Base using (id; flip; _$′_; _∘′_) open import Level using (Level; suc; _⊔_) private variable f g g₁ g₂ : Level A B C : Set f ------------------------------------------------------------------------ -- The type of raw monads record RawMonad (F : Set f → Set g) : Set (suc f ⊔ g) where infixl 1 _>>=_ _>>_ _>=>_ infixr 1 _=<<_ _<=<_ field rawApplicative : RawApplicative F _>>=_ : F A → (A → F B) → F B open RawApplicative rawApplicative public _>>_ : F A → F B → F B _>>_ = _*>_ _=<<_ : (A → F B) → F A → F B _=<<_ = flip _>>=_ Kleisli : Set f → Set f → Set (f ⊔ g) Kleisli A B = A → F B _>=>_ : Kleisli A B → Kleisli B C → Kleisli A C (f >=> g) a = f a >>= g _<=<_ : Kleisli B C → Kleisli A B → Kleisli A C _<=<_ = flip _>=>_ when : Bool → F ⊤ → F ⊤ when true m = m when false m = pure _ unless : Bool → F ⊤ → F ⊤ unless = when ∘′ not -- When level g=f, a join/μ operator is definable module Join {F : Set f → Set f} (M : RawMonad F) where open RawMonad M join : F (F A) → F A join = _>>= id -- Smart constructor module _ where open RawMonad open RawApplicative mkRawMonad : (F : Set f → Set g) → (pure : ∀ {A} → A → F A) → (bind : ∀ {A B} → F A → (A → F B) → F B) → RawMonad F mkRawMonad F pure _>>=_ .rawApplicative = mkRawApplicative _ pure $′ λ mf mx → do f ← mf x ← mx pure (f x) mkRawMonad F pure _>>=_ ._>>=_ = _>>=_ ------------------------------------------------------------------------ -- The type of raw monads with a zero record RawMonadZero (F : Set f → Set g) : Set (suc f ⊔ g) where field rawMonad : RawMonad F rawEmpty : RawEmpty F open RawMonad rawMonad public open RawEmpty rawEmpty public rawApplicativeZero : RawApplicativeZero F rawApplicativeZero = record { rawApplicative = rawApplicative ; rawEmpty = rawEmpty } ------------------------------------------------------------------------ -- The type of raw monadplus record RawMonadPlus (F : Set f → Set g) : Set (suc f ⊔ g) where field rawMonadZero : RawMonadZero F rawChoice : RawChoice F open RawMonadZero rawMonadZero public open RawChoice rawChoice public rawAlternative : RawAlternative F rawAlternative = record { rawApplicativeZero = rawApplicativeZero ; rawChoice = rawChoice } ------------------------------------------------------------------------ -- The type of raw monad transformer -- F has been RawMonadT'd as TF record RawMonadTd (F : Set f → Set g₁) (TF : Set f → Set g₂) : Set (suc f ⊔ g₁ ⊔ g₂) where field lift : F A → TF A rawMonad : RawMonad TF open RawMonad rawMonad public RawMonadT : (T : (Set f → Set g₁) → (Set f → Set g₂)) → Set (suc f ⊔ suc g₁ ⊔ g₂) RawMonadT T = ∀ {M} → RawMonad M → RawMonadTd M (T M)