Section State.
Variable M : Type -> Type.
Variable S : Type.
Context {EQM : EqM M}.
Context {HM: Monad M}.
Context {HEQP: @EqMProps M _ EQM}.
Context {ML: @MonadLaws M _ HM}.
Global Instance EqM_stateTM : EqM (stateT S M).
Instance MonadLaws_stateTM : @MonadLaws (stateT S M) _ _.
Context {IM: Iter (Kleisli M) sum}.
Context {CM: Iterative (Kleisli M) sum}.
Definition iso {a b:Type} (sab : S * (a + b)) : (S * a) + (S * b) :=
match sab with
| (s, inl x) => inl (s, x)
| (s, inr y) => inr (s, y)
end.
Definition iso_inv {a b:Type} (sab : (S * a) + (S * b)) : S * (a + b) :=
match sab with
| inl (s, a) => (s, inl a)
| inr (s, b) => (s, inr b)
end.
Definition internalize {a b:Type} (f : Kleisli (stateT S M) a b) : Kleisli M (S * a) (S * b) :=
fun (sa : S * a) => f (snd sa) (fst sa).

Lemma internalize_pure {a b c} (f : Kleisli (stateT S M) a b) (g : S * b -> S * c) :
internalize f >>> pure g   ⩯   (internalize (f >>> (fun b s => ret (g (s,b))))).