Source code on Github{-# OPTIONS --safe #-}
module Prelude.Monad where
open import Prelude.Init; open SetAsType
open import Prelude.Functor
open import Prelude.Applicative
open import Prelude.General
private variable A : Type ℓ; B : Type ℓ′; C : Type ℓ″; M : Type↑
record Monad (M : Type↑) : Typeω where
infixl 1 _>>=_ _>>_ _≫=_ _≫_ _>=>_
infixr 1 _=<<_ _=≪_ _<=<_
field
overlap ⦃ super ⦄ : Applicative M
return : A → M A
_>>=_ : M A → (A → M B) → M B
_>>_ : M A → M B → M B
m₁ >> m₂ = m₁ >>= λ _ → m₂
_=<<_ : (A → M B) → M A → M B
f =<< c = c >>= f
_≫=_ = _>>=_; _≫_ = _>>_; _=≪_ = _=<<_
_>=>_ : (A → M B) → (B → M C) → (A → M C)
f >=> g = _=<<_ g ∘ f
_<=<_ : (B → M C) → (A → M B) → (A → M C)
g <=< f = f >=> g
join : M (M A) → M A
join m = m >>= id
open Monad ⦃...⦄ public
record MonadLaws (M : Type↑) ⦃ _ : Monad M ⦄ : Typeω where
field
>>=-identityˡ : ∀ {A : Type ℓ} {B : Type ℓ′} {a : A} {h : A → M B} →
(return a >>= h) ≡ h a
>>=-identityʳ : ∀ {A : Type ℓ} (m : M A) →
(m >>= return) ≡ m
>>=-assoc : ∀ {A : Type ℓ} {B : Type ℓ′} {C : Type ℓ″} (m : M A) {g : A → M B} {h : B → M C} →
((m >>= g) >>= h) ≡ (m >>= (λ x → g x >>= h))
open MonadLaws ⦃...⦄ public
record Lawful-Monad (M : Type↑) : Typeω where
field ⦃ isMonad ⦄ : Monad M
⦃ hasMonadLaws ⦄ : MonadLaws M
open Lawful-Monad ⦃...⦄ using () public
instance
mkLawful-Monad : ⦃ _ : Monad M ⦄ → ⦃ MonadLaws M ⦄ → Lawful-Monad M
mkLawful-Monad = record {}
record Monad′ (M : Type[ ℓ ↝ ℓ′ ]) : Type (lsuc ℓ ⊔ₗ ℓ′) where
infixl 1 _>>=′_ _>>′_ _≫=′_ _≫′_ _>=>′_
infixr 1 _=<<′_ _=≪′_ _<=<′_
field
return′ : A → M A
_>>=′_ : M A → (A → M B) → M B
_>>′_ : M A → M B → M B
m₁ >>′ m₂ = m₁ >>=′ λ _ → m₂
_=<<′_ : (A → M B) → M A → M B
f =<<′ c = c >>=′ f
_>=>′_ : (A → M B) → (B → M C) → (A → M C)
f >=>′ g = _=<<′_ g ∘ f
_<=<′_ : (B → M C) → (A → M B) → (A → M C)
g <=<′ f = f >=>′ g
_≫=′_ = _>>=′_; _≫′_ = _>>′_; _=≪′_ = _=<<′_
open Monad′ ⦃...⦄ public
record Monad₀ (M : Type↑) : Typeω where
field ⦃ isMonad ⦄ : Monad M
⦃ isApplicative₀ ⦄ : Applicative₀ M
open Monad₀ ⦃...⦄ using () public
instance
mkMonad₀ : ⦃ Monad M ⦄ → ⦃ Applicative₀ M ⦄ → Monad₀ M
mkMonad₀ = record {}
record Monad⁺ (M : Type↑) : Typeω where
field ⦃ isMonad ⦄ : Monad M
⦃ isAlternative ⦄ : Alternative M
open Monad⁺ ⦃...⦄ using () public
instance
mkMonad⁺ : ⦃ Monad M ⦄ → ⦃ Alternative M ⦄ → Monad⁺ M
mkMonad⁺ = record {}
instance
Monad-Maybe : Monad Maybe
Monad-Maybe = λ where
.return → pure
._>>=_ m f → maybe f nothing m
MonadLaws-Maybe : MonadLaws Maybe
MonadLaws-Maybe = λ where
.>>=-identityˡ → refl
.>>=-identityʳ → λ where
(just _) → refl
nothing → refl
.>>=-assoc → λ where
(just _) → refl
nothing → refl
Monad-List : Monad List
Monad-List = λ where
.return → pure
._>>=_ → flip concatMap
Monad-TC : Monad Meta.TC
Monad-TC = record {R}
where import Reflection as R using (return) renaming (bindTC to _>>=_)
module _ ⦃ _ : Monad M ⦄ where
mapM : (A → M B) → List A → M (List B)
mapM f [] = return []
mapM f (x ∷ xs) = ⦇ f x ∷ mapM f xs ⦈
concatMapM : (A → M (List B)) → List A → M (List B)
concatMapM f xs = concat <$> mapM f xs
forM : List A → (A → M B) → M (List B)
forM [] _ = return []
forM (x ∷ xs) f = ⦇ f x ∷ forM xs f ⦈
concatForM : List A → (A → M (List B)) → M (List B)
concatForM xs f = concat <$> forM xs f
return⊤ void : M A → M ⊤
return⊤ k = k ≫ return tt
void = return⊤
filterM : (A → M Bool) → List A → M (List A)
filterM _ [] = return []
filterM p (x ∷ xs) = do
b ← p x
((if b then [ x ] else []) ++_) <$> filterM p xs
do-pure : ∀ {A : Type ℓ} {x : A} {mx : Maybe A} {f : A → Bool}
→ mx ≡ just x
→ f x ≡ true
→ M.fromMaybe false (mx >>= pure ∘ f) ≡ true
do-pure refl f≡ rewrite f≡ = refl
private
_ : (return 5 >>= just) ≡ just 5
_ = refl
_ : (return 5 >>= just) ≡ just 5
_ = >>=-identityʳ _
_ : ⦃ _ : Lawful-Monad M ⦄ → (ℕ → M ℕ)
_ = return
_ : Lawful-Monad Maybe
_ = itω