69 lines
1.8 KiB
Text
69 lines
1.8 KiB
Text
/-
|
||
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import init.logic init.monad init.alternative init.prod
|
||
|
||
def state (S : Type) (A : Type) : Type :=
|
||
S → A × S
|
||
|
||
section
|
||
variables {S : Type} {A B : Type}
|
||
|
||
@[inline] def state_fmap (f : A → B) (a : state S A) : state S B :=
|
||
λ s, match (a s) with (a', s') := (f a', s') end
|
||
|
||
@[inline] def state_return (a : A) : state S A :=
|
||
λ s, (a, s)
|
||
|
||
@[inline] def state_bind (a : state S A) (b : A → state S B) : state S B :=
|
||
λ s, match (a s) with (a', s') := b a' s' end
|
||
|
||
instance (S : Type) : monad (state S) :=
|
||
⟨@state_fmap S, @state_return S, @state_bind S⟩
|
||
end
|
||
|
||
namespace state
|
||
@[inline] def read {S : Type} : state S S :=
|
||
λ s, (s, s)
|
||
|
||
@[inline] def write {S : Type} : S → state S unit :=
|
||
λ s' s, ((), s')
|
||
end state
|
||
|
||
def stateT (S : Type) (M : Type → Type) [monad M] (A : Type) : Type :=
|
||
S → M (A × S)
|
||
|
||
section
|
||
variable {S : Type}
|
||
variable {M : Type → Type}
|
||
variable [monad M]
|
||
variables {A B : Type}
|
||
|
||
def stateT_fmap (f : A → B) (act : stateT S M A) : stateT S M B :=
|
||
λ s, show M (B × S), from
|
||
do (a, new_s) ← act s,
|
||
return (f a, new_s)
|
||
|
||
def stateT_return (a : A) : stateT S M A :=
|
||
λ s, show M (A × S), from
|
||
return (a, s)
|
||
|
||
def stateT_bind (act₁ : stateT S M A) (act₂ : A → stateT S M B) : stateT S M B :=
|
||
λ s, show M (B × S), from
|
||
do (a, new_s) ← act₁ s,
|
||
act₂ a new_s
|
||
end
|
||
|
||
instance (S : Type) (M : Type → Type) [monad M] : monad (stateT S M) :=
|
||
⟨@stateT_fmap S M _, @stateT_return S M _, @stateT_bind S M _⟩
|
||
|
||
namespace stateT
|
||
def read {S : Type} {M : Type → Type} [monad M] : stateT S M S :=
|
||
λ s, return (s, s)
|
||
|
||
def write {S : Type} {M : Type → Type} [monad M] : S → stateT S M unit :=
|
||
λ s' s, return ((), s')
|
||
end stateT
|