@@ -119,6 +119,15 @@ lemma run_get (k : σ → FreeState σ α) (s₀ : σ) :
119119lemma run_set (s' : σ) (k : PUnit → FreeState σ α) (s₀ : σ) :
120120 run (liftBind (.set s') k) s₀ = run (k .unit) s' := rfl
121121
122+ @[simp]
123+ lemma run_bind (x : FreeState σ α) (f : α → FreeState σ β) (s₀ : σ) :
124+ run (x.bind f) s₀ = let p := x.run s₀; (f p.1 ).run p.2 := by
125+ induction x generalizing f s₀ with
126+ | pure => simp
127+ | liftBind op cont ih =>
128+ rw [FreeM.liftBind_bind]
129+ cases op <;> simp [run, ih]
130+
122131/-- Run a state computation, returning only the result. -/
123132def run' (c : FreeState σ α) (s₀ : σ) : α := (run c s₀).1
124133
@@ -140,6 +149,11 @@ lemma run'_get (k : σ → FreeState σ α) (s₀ : σ) :
140149lemma run'_set (s' : σ) (k : PUnit → FreeState σ α) (s₀ : σ) :
141150 run' (liftBind (.set s') k) s₀ = run' (k .unit) s' := rfl
142151
152+ @[simp]
153+ lemma run'_bind (x : FreeState σ α) (f : α → FreeState σ β) (s₀ : σ) :
154+ run' (x.bind f) s₀ = let p := x.run s₀; (f p.1 ).run' p.2 :=
155+ congr_arg Prod.fst <| run_bind _ _ _
156+
143157end FreeState
144158
145159/-! ### Writer Monad via `FreeM` -/
@@ -198,6 +212,16 @@ def run [Monoid ω] : FreeWriter ω α → α × ω
198212lemma run_pure [Monoid ω] (a : α) :
199213 run (.pure a : FreeWriter ω α) = (a, 1 ) := rfl
200214
215+ @[simp]
216+ lemma run_bind [Monoid ω] (x : FreeWriter ω α) (f : α → FreeWriter ω β) :
217+ run (x.bind f) = let p := run x; ((f p.1 ).run.1 , p.2 * (f p.1 ).run.2 ) := by
218+ induction x generalizing f with
219+ | pure => simp
220+ | liftBind op cont ih =>
221+ rw [FreeM.liftBind_bind]
222+ cases op
223+ simp [run, ih, mul_assoc]
224+
201225@[simp]
202226lemma run_liftBind_tell [Monoid ω] (w : ω) (k : PUnit → FreeWriter ω α) :
203227 run (liftBind (.tell w) k) = (let (a, w') := run (k .unit); (a, w * w')) := rfl
@@ -317,6 +341,16 @@ theorem run_toContT {α : Type u} (comp : FreeCont r α) (k : α → r) :
317341lemma run_pure (a : α) (k : α → r) :
318342 run (.pure a : FreeCont r α) k = k a := rfl
319343
344+ @[simp]
345+ lemma run_bind (x : FreeCont r α) (f : α → FreeCont r β) (k : β → r) :
346+ run (x.bind f) k = run x (fun i => run (f i) k) := by
347+ induction x generalizing k with
348+ | pure a => rfl
349+ | liftBind op cont ih =>
350+ rw [FreeM.liftBind_bind]
351+ cases op
352+ simp [run, ih]
353+
320354@[simp]
321355lemma run_liftBind_callCC (g : (α → r) → r)
322356 (cont : α → FreeCont r β) (k : β → r) :
@@ -401,6 +435,14 @@ lemma run_pure (a : α) (s₀ : σ) :
401435lemma run_read (k : σ → FreeReader σ α) (s₀ : σ) :
402436 run (liftBind .read k) s₀ = run (k s₀) s₀ := rfl
403437
438+ @[simp]
439+ lemma run_bind (x : FreeReader σ α) (f : α → FreeReader σ β) (s₀ : σ) :
440+ run (x.bind f) s₀ = run (f <| run x s₀) s₀ := by
441+ induction x generalizing s₀ with
442+ | pure a => rfl
443+ | liftBind op cont ih =>
444+ cases op; apply ih
445+
404446instance instMonadWithReaderOf : MonadWithReaderOf σ (FreeReader σ) where
405447 withReader {α} f m :=
406448 let rec go : FreeReader σ α → FreeReader σ α
0 commit comments