Documentation

Batteries.Control.LawfulMonadState

Laws for Monads with State #

This file defines a typeclass for MonadStateOf with compatible get and set operations.

Note that we use MonadStateOf over MonadState as the first induces the second, but we phrase things using MonadStateOf.set and MonadState.get as those are the versions that are available at the top level namespace.

@[simp]
theorem monadStateOf_get_eq_get {σ : Type u_1} {m : Type u_1 → Type u_2} [MonadStateOf σ m] :

The namespaced MonadStateOf.get is equal to the MonadState provided get.

@[simp]
theorem monadStateOf_modifyGet_eq_modifyGet {σ : Type u_1} {m : Type u_1 → Type u_2} {α : Type u_1} [MonadStateOf σ m] (f : σα × σ) :

The namespaced MonadStateOf.modifyGet is equal to the MonadState provided modifyGet.

@[simp]
theorem liftM_get {σ : Type u_1} {m : Type u_1 → Type u_2} {n : Type u_1 → Type u_3} [MonadStateOf σ m] [MonadLift m n] :
@[simp]
theorem liftM_set {σ : Type u_1} {m : Type u_1 → Type u_2} {n : Type u_1 → Type u_3} [MonadStateOf σ m] [MonadLift m n] (s : σ) :
liftM (set s) = set s
@[simp]
theorem liftM_modify {σ : Type u_1} {m : Type u_1 → Type u_2} {n : Type u_1 → Type u_3} [MonadStateOf σ m] [MonadLift m n] (f : σσ) :
@[simp]
theorem liftM_modifyGet {σ α : Type u_1} {m : Type u_1 → Type u_2} {n : Type u_1 → Type u_3} [MonadStateOf σ m] [MonadLift m n] (f : σα × σ) :
@[simp]
theorem liftM_getModify {σ : Type u_1} {m : Type u_1 → Type u_2} {n : Type u_1 → Type u_3} [MonadStateOf σ m] [MonadLift m n] (f : σσ) :
class LawfulMonadStateOf (σ : semiOutParam (Type u_1)) (m : Type u_1 → Type u_2) [Monad m] [MonadStateOf σ m] extends LawfulMonad m :

Class for well behaved state monads, extending the base MonadState type. Requires that modifyGet is equal to the same definition with only get and set, that get is idempotent if the result isn't used, and that get after set returns exactly the value that was previously set.

Instances
    @[simp]
    theorem LawfulMonadStateOf.get_seqRight {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (mx : m α) :
    get *> mx = mx
    @[simp]
    theorem LawfulMonadStateOf.seqLeft_get {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (mx : m α) :
    mx <* get = mx
    @[simp]
    theorem LawfulMonadStateOf.get_map_const {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (x : α) :
    (fun (x_1 : σ) => x) <$> get = pure x
    theorem LawfulMonadStateOf.get_bind_get {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] :
    (do let __discrget have x : σ := __discr get) = get
    @[simp]
    theorem LawfulMonadStateOf.get_bind_set {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] :
    (do let sget set s) = pure PUnit.unit
    @[simp]
    theorem LawfulMonadStateOf.get_bind_map_set {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (f : σPUnitα) :
    (do let sget f s <$> set s) = do let __do_liftget pure (f __do_lift PUnit.unit)
    @[simp]
    theorem LawfulMonadStateOf.set_bind_get_bind {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (s : σ) (f : σm α) :
    (do set s let s'get f s') = do set s f s
    @[simp]
    theorem LawfulMonadStateOf.set_bind_map_get {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (f : σα) (s : σ) :
    (do set s f <$> get) = do set s pure (f s)
    @[simp]
    theorem LawfulMonadStateOf.set_bind_set_bind {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (s s' : σ) (mx : m α) :
    (do set s set s' mx) = do set s' mx
    @[simp]
    theorem LawfulMonadStateOf.set_bind_map_set {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (s s' : σ) (f : PUnitα) :
    (do set s f <$> set s') = f <$> set s'
    theorem LawfulMonadStateOf.modifyGetThe_eq {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (f : σα × σ) :
    modifyGetThe σ f = do let zf <$> get set z.snd pure z.fst
    theorem LawfulMonadStateOf.modify_eq {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (f : σσ) :
    modify f = do let __do_liftget set (f __do_lift)
    theorem LawfulMonadStateOf.modifyThe_eq {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (f : σσ) :
    modifyThe σ f = do let __do_liftget set (f __do_lift)
    theorem LawfulMonadStateOf.getModify_eq {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (f : σσ) :
    getModify f = do let sget set (f s) pure s
    theorem LawfulMonadStateOf.modifyGet_eq' {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (f : σα × σ) :
    modifyGet f = do let sget modify (Prod.snd f) pure (f s).fst

    Version of modifyGet_eq that preserves an call to modify.

    @[simp]
    theorem LawfulMonadStateOf.modify_id {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] :
    @[simp]
    theorem LawfulMonadStateOf.getModify_id {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] :
    @[simp]
    theorem LawfulMonadStateOf.set_bind_modify {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (s : σ) (f : σσ) :
    (do set s modify f) = set (f s)
    @[simp]
    theorem LawfulMonadStateOf.set_bind_modify_bind {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (s : σ) (f : σσ) (mx : PUnitm α) :
    (do set s let umodify f mx u) = do set (f s) mx PUnit.unit
    @[simp]
    theorem LawfulMonadStateOf.set_bind_modifyGet {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (s : σ) (f : σα × σ) :
    (do set s modifyGet f) = do set (f s).snd pure (f s).fst
    @[simp]
    theorem LawfulMonadStateOf.set_bind_modifyGet_bind {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α β : Type u_1} (s : σ) (f : σα × σ) (mx : αm β) :
    (do set s let xmodifyGet f mx x) = do set (f s).snd mx (f s).fst
    @[simp]
    theorem LawfulMonadStateOf.set_bind_getModify {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (s : σ) (f : σσ) :
    (do set s getModify f) = do set (f s) pure s
    @[simp]
    theorem LawfulMonadStateOf.set_bind_getModify_bind {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (s : σ) (f : σσ) (mx : σm α) :
    (do set s let xgetModify f mx x) = do set (f s) mx s
    @[simp]
    theorem LawfulMonadStateOf.modify_bind_modify {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (f g : σσ) :
    (do modify f modify g) = modify (g f)
    @[simp]
    theorem LawfulMonadStateOf.modify_bind_modifyGet {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {α : Type u_1} (f : σσ) (g : σα × σ) :
    (do modify f modifyGet g) = modifyGet (g f)
    @[simp]
    theorem LawfulMonadStateOf.getModify_bind_modify {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (f : σσ) (g : σσσ) :
    (do let sgetModify f modify (g s)) = do let sget modify (g s f)
    theorem LawfulMonadStateOf.modify_comm_of_comp_comm {σ : Type u_1} {m : Type u_1 → Type u_2} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] {f g : σσ} (h : f g = g f) :
    (do modify f modify g) = do modify g modify f
    theorem LawfulMonadStateOf.modify_bind_get {σ : Type u_2} {m : Type u_2 → Type u_1} [Monad m] [MonadStateOf σ m] [LawfulMonadStateOf σ m] (f : σσ) :
    (do modify f get) = do let sget modify f pure (f s)
    instance LawfulMonadStateOf.instStateTOfLawfulMonad {m : Type u_1 → Type u_2} {σ : Type u_1} [Monad m] [LawfulMonad m] :

    StateT has lawful state operations if the underlying monad is lawful. This is applied for StateM as well due to the reducibility of that definition.

    instance LawfulMonadStateOf.instStateCpsT {σ : Type u_1} {m : Type u_1 → Type u_2} :

    The continuation passing state monad variant StateCpsT always has lawful state instance.

    The EStateM monad always has a lawful state instance.

    If the underlying monad m has a lawful state instance, then the induced state instance on ReaderT ρ m will also be lawful.