State
class State[S,T]( init : (S -> [S,T]) )
: MonadMapApply[T]
{
bind[A] : (T -> State[S,A]) -> State[S,A] = f -> State[S,A]( s -> init(s) | (s,t) -> f(t).init(s) )
map [A] : ([S,T] -> [S,A]) -> State[S,A] = f -> State[S,A]( s -> f(init(s)) )
Applicative.lift = t -> State[S,T]( s -> (s,t) )
}
State.map
, apply
, and bind
enable the composition of the functions (containing the
implied morphism : T -> A
) which do and
do not operate on state of type S
.State
(a Monad
) eliminates the
boilerplate of threading some state across functions that don't
access that state so as to compose these with functions that do
access that state. This allows reuse of functions without having to
code separate functions for each permutation of state that one might
one to compose with. The State monad is roughly analogous to a
threadable scope for global variables, i.e. that state is
encapsulated, so that state is only accessible to functions in the
composition, and thus the functions are pure w.r.t. that state. Thus
the state effects are transparent (the functions operate on that
state via inputs and return value only), delimited, and composable.Traversable
.State.lift : T -> State[S,T]
is an example of a more
general function of type : T -> State[S,A]
, which
is internally a combination of operations of types : S ->
S
and : T -> A
.State.lift
, these are both identity operations s
-> s
and t -> t
, which are combined to
construct a 2-tuple (s,t)
of type [S,T]
.Traversable
.T
and
outputs an instance of type State[S,A]
. The output of
type State[S,A]
, contains the constructor parameter
field init
which is set to a function that inputs an
initial state of type S
, and outputs the 2-tuple of
type [S,A]
, which is a combination of the operations
of types : S -> S
and : T -> A
.
The function instance stored in init
is called when it
is desired to evaluate any state computations (that are stored in
nested closures and to) return the 2-tuple.: S -> S
operation can modify the instance of
state type S
, or output it unmodified.: T -> A
operation can output a new instance of
type A
, or it can output the input type T
(i.e. A
can be a T
).State.bind : State[S,T] (T -> State[S,A]) -> State[S,A]
composes the instance of this
of type State[S,T], with
a function of the general model. The following are then derived from
State.bind
: Functor.map
, Applicative.apply
,
Monad.join
, and Monad.compose
.Event
, which addresses many issues
about the nature of programming with state transitions.