| /- | |
| Copyright (c) 2021 Microsoft Corporation. All rights reserved. | |
| Released under Apache 2.0 license as described in the file LICENSE. | |
| Authors: Leonardo de Moura | |
| -/ | |
| prelude | |
| import Init.Control.Lawful | |
| /-! | |
| The Exception monad transformer using CPS style. | |
| -/ | |
| def ExceptCpsT (ε : Type u) (m : Type u → Type v) (α : Type u) := (β : Type u) → (α → m β) → (ε → m β) → m β | |
| namespace ExceptCpsT | |
| @[always_inline, inline] | |
| def run {ε α : Type u} [Monad m] (x : ExceptCpsT ε m α) : m (Except ε α) := | |
| x _ (fun a => pure (Except.ok a)) (fun e => pure (Except.error e)) | |
| @[always_inline, inline] | |
| def runK {ε α : Type u} (x : ExceptCpsT ε m α) (s : ε) (ok : α → m β) (error : ε → m β) : m β := | |
| x _ ok error | |
| @[always_inline, inline] | |
| def runCatch [Monad m] (x : ExceptCpsT α m α) : m α := | |
| x α pure pure | |
| @[always_inline] | |
| instance : Monad (ExceptCpsT ε m) where | |
| map f x := fun _ k₁ k₂ => x _ (fun a => k₁ (f a)) k₂ | |
| pure a := fun _ k _ => k a | |
| bind x f := fun _ k₁ k₂ => x _ (fun a => f a _ k₁ k₂) k₂ | |
| instance : LawfulMonad (ExceptCpsT σ m) := by | |
| refine' { .. } <;> intros <;> rfl | |
| instance : MonadExceptOf ε (ExceptCpsT ε m) where | |
| throw e := fun _ _ k => k e | |
| tryCatch x handle := fun _ k₁ k₂ => x _ k₁ (fun e => handle e _ k₁ k₂) | |
| @[always_inline, inline] | |
| def lift [Monad m] (x : m α) : ExceptCpsT ε m α := | |
| fun _ k _ => x >>= k | |
| instance [Monad m] : MonadLift m (ExceptCpsT σ m) where | |
| monadLift := ExceptCpsT.lift | |
| instance [Inhabited ε] : Inhabited (ExceptCpsT ε m α) where | |
| default := fun _ _ k₂ => k₂ default | |
| @[simp] theorem run_pure [Monad m] : run (pure x : ExceptCpsT ε m α) = pure (Except.ok x) := rfl | |
| @[simp] theorem run_lift {α ε : Type u} [Monad m] (x : m α) : run (ExceptCpsT.lift x : ExceptCpsT ε m α) = (x >>= fun a => pure (Except.ok a) : m (Except ε α)) := rfl | |
| @[simp] theorem run_throw [Monad m] : run (throw e : ExceptCpsT ε m β) = pure (Except.error e) := rfl | |
| @[simp] theorem run_bind_lift [Monad m] (x : m α) (f : α → ExceptCpsT ε m β) : run (ExceptCpsT.lift x >>= f : ExceptCpsT ε m β) = x >>= fun a => run (f a) := rfl | |
| @[simp] theorem run_bind_throw [Monad m] (e : ε) (f : α → ExceptCpsT ε m β) : run (throw e >>= f : ExceptCpsT ε m β) = run (throw e) := rfl | |
| @[simp] theorem runCatch_pure [Monad m] : runCatch (pure x : ExceptCpsT α m α) = pure x := rfl | |
| @[simp] theorem runCatch_lift {α : Type u} [Monad m] [LawfulMonad m] (x : m α) : runCatch (ExceptCpsT.lift x : ExceptCpsT α m α) = x := by | |
| simp [runCatch, lift] | |
| @[simp] theorem runCatch_throw [Monad m] : runCatch (throw a : ExceptCpsT α m α) = pure a := rfl | |
| @[simp] theorem runCatch_bind_lift [Monad m] (x : m α) (f : α → ExceptCpsT β m β) : runCatch (ExceptCpsT.lift x >>= f : ExceptCpsT β m β) = x >>= fun a => runCatch (f a) := rfl | |
| @[simp] theorem runCatch_bind_throw [Monad m] (e : β) (f : α → ExceptCpsT β m β) : runCatch (throw e >>= f : ExceptCpsT β m β) = pure e := rfl | |
| end ExceptCpsT |