Built with
doc-gen4, running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+โCtrl+โto navigate,
Ctrl+๐ฑ๏ธto focus.
On Mac, use
Cmdinstead of
Ctrl.
/-
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Simon Hudon, E.W.Ayers
-/
import Mathlib.Algebra.Group.Defs
/-!
# Writer monads
This file introduces monads for managing immutable, appendable state.
Common applications are logging monads where the monad logs messages as the
computation progresses.
## References
- https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Writer-Class.html
- [Original Mark P Jones article introducing `Writer`](https://web.cecs.pdx.edu/~mpj/pubs/springschool.html)
-/
def WriterT (ฯ : Type u) (M : Type u โ Type v) (ฮฑ : Type u) : Type v :=
M (ฮฑ ร ฯ)
@[reducible]
def Writer ฯ := WriterT ฯ Id
class MonadWriter (ฯ : outParam (Type u)) (M : Type u โ Type v) where
tell : ฯ โ M PUnit
listen {ฮฑ} : M ฮฑ โ M (ฮฑ ร ฯ)
pass {ฮฑ} : M (ฮฑ ร (ฯ โ ฯ)) โ M ฮฑ
export MonadWriter (tell listen pass)
variable {M : Type u โ Type v} [Monad: (Type ?u.96 โ Type ?u.95) โ Type (max(?u.96+1)?u.95)
Monad M]
instance [MonadWriter ฯ M] : MonadWriter ฯ (ReaderT ฯ M) where
tell w := (tell w : M _)
listen x r := listen <| x r
pass x r := pass <| x r
instance [MonadWriter ฯ M] : MonadWriter ฯ (StateT ฯ M) where
tell w := (tell w : M _)
listen x s := (fun ((a,w), s) โฆ ((a,s), w)) <$> listen (x s)
pass x s := pass <| (fun ((a, f), s) โฆ ((a, s), f)) <$> (x s)
namespace WriterT
protected def mk {ฯ : Type u} (cmd : M (ฮฑ ร ฯ)) : WriterT ฯ M ฮฑ:= cmd
protected def run {ฯ : Type u} (cmd : WriterT ฯ M ฮฑ) : M (ฮฑ ร ฯ) := cmd
protected def runThe (ฯ : Type u) (cmd : WriterT ฯ M ฮฑ) : M (ฮฑ ร ฯ) := cmd
variable {ฯ : Type u} {ฮฑ ฮฒ : Type u}
/-- Creates an instance of Monad, with an explicitly given empty and append operation.
Previously, this would have used an instance of `[Monoid ฯ]` as input.
In practice, however, WriterT is used for logging and creating lists so restricting to
monoids with `Mul` and `One` can make `WriterT` cumbersome to use.
This is used to derive instances for both `[EmptyCollection ฯ] [Append ฯ]` and `[Monoid ฯ]`.
-/
def monad (empty : ฯ) (append : ฯ โ ฯ โ ฯ) : Monad: (Type ?u.2438 โ Type ?u.2437) โ Type (max(?u.2438+1)?u.2437)
Monad (WriterT ฯ M) where
map := fun f (cmd : M _) โฆ WriterT.mk: {M : Type ?u.2481 โ Type ?u.2480} โ {ฮฑ ฯ : Type ?u.2481} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ (fun (a,w) โฆ (f a, w)) <$> cmd
pure := fun a โฆ pure: {f : Type ?u.2564 โ Type ?u.2563} โ [self : Pure f] โ {ฮฑ : Type ?u.2564} โ ฮฑ โ f ฮฑ
pure (f := M) (a, empty)
bind := fun (cmd : M _) f โฆ
WriterT.mk: {M : Type ?u.2692 โ Type ?u.2691} โ {ฮฑ ฯ : Type ?u.2692} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ cmd >>= fun (a, wโ) โฆ
(fun (b, wโ) โฆ (b, append wโ wโ)) <$> (f a)
/-- Lift an `M` to a `WriterT ฯ M`, using the given `empty` as the monoid unit. -/
protected def liftTell (empty : ฯ) : MonadLift M (WriterT ฯ M) where
monadLift := fun cmd โฆ WriterT.mk: {M : Type ?u.4470 โ Type ?u.4469} โ {ฮฑ ฯ : Type ?u.4470} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ (fun a โฆ (a, empty)) <$> cmd
instance [EmptyCollection: Type ?u.4646 โ Type ?u.4646
EmptyCollection ฯ] [Append ฯ] : Monad: (Type ?u.4653 โ Type ?u.4652) โ Type (max(?u.4653+1)?u.4652)
Monad (WriterT ฯ M) := monad โ
(ยท ++ ยท): ฯ โ ฯ โ ฯ
(ยท ++ ยท)
instance [EmptyCollection: Type ?u.4920 โ Type ?u.4920
EmptyCollection ฯ] : MonadLift M (WriterT ฯ M) := WriterT.liftTell โ
instance [Monoid ฯ] : Monad: (Type ?u.5115 โ Type ?u.5114) โ Type (max(?u.5115+1)?u.5114)
Monad (WriterT ฯ M) := monad 1 (ยท * ยท): ฯ โ ฯ โ ฯ
(ยท * ยท)
instance [Monoid ฯ] : MonadLift M (WriterT ฯ M) := WriterT.liftTell 1
instance : MonadWriter ฯ (WriterT ฯ M) where
tell := fun w โฆ WriterT.mk: {M : Type ?u.5724 โ Type ?u.5723} โ {ฮฑ ฯ : Type ?u.5724} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ pure: {f : Type ?u.5734 โ Type ?u.5733} โ [self : Pure f] โ {ฮฑ : Type ?u.5734} โ ฮฑ โ f ฮฑ
pure (โจโฉ, w)
listen := fun cmd โฆ WriterT.mk: {M : Type ?u.5802 โ Type ?u.5801} โ {ฮฑ ฯ : Type ?u.5802} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ (fun (a,w) โฆ ((a,w), w)) <$> cmd
pass := fun cmd โฆ WriterT.mk: {M : Type ?u.5865 โ Type ?u.5864} โ {ฮฑ ฯ : Type ?u.5865} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ (fun ((a,f), w) โฆ (a, f w)) <$> cmd
instance [MonadExcept ฮต M] : MonadExcept ฮต (WriterT ฯ M) where
throw := fun e โฆ WriterT.mk: {M : Type ?u.6696 โ Type ?u.6695} โ {ฮฑ ฯ : Type ?u.6696} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ throw e
tryCatch := fun cmd c โฆ WriterT.mk: {M : Type ?u.6745 โ Type ?u.6744} โ {ฮฑ ฯ : Type ?u.6745} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ tryCatch cmd fun e โฆ (c e).run
instance [MonadLiftT: (Type ?u.7065 โ Type ?u.7064) โ (Type ?u.7065 โ Type ?u.7063) โ Type (max(max(?u.7065+1)?u.7064)?u.7063)
MonadLiftT M (WriterT ฯ M)] : MonadControl M (WriterT ฯ M) where
stM := fun ฮฑ โฆ ฮฑ ร ฯ
liftWith f := liftM: {m : Type ?u.7127 โ Type ?u.7126} โ
{n : Type ?u.7127 โ Type ?u.7125} โ [self : MonadLiftT m n] โ {ฮฑ : Type ?u.7127} โ m ฮฑ โ n ฮฑ
liftM <| f fun x โฆ x.run
restoreM := WriterT.mk: {M : Type ?u.7195 โ Type ?u.7194} โ {ฮฑ ฯ : Type ?u.7195} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk
instance : MonadFunctor M (WriterT ฯ M) where
monadMap := fun k (w : M _) โฆ WriterT.mk: {M : Type ?u.7416 โ Type ?u.7415} โ {ฮฑ ฯ : Type ?u.7416} โ M (ฮฑ ร ฯ) โ WriterT ฯ M ฮฑ
WriterT.mk $ k w
end WriterT