The State
type can be used to store some state along with a computation.
State
instances should be obtained via the get
, gets
, put
, and modify
static properties on the State
object. These instances describe the different
ways to access and modify the stateful computation that will eventually be
evaluated and are described in further detail below.
A State
transformer is also available via State.T
which can be used to
extend some monad with stateful behaviour.
State
instances are primarily interacted with and composed via the chain
method of the various static instances available on the State
type object. To
access the current state, State.get
is a static instance that can be used to
provide the state to the chain
, ap
and map
. Similarly, State.gets(fn)
can provide the state transformed by the provided fn
function. To change the
state of the computation, State.put(newValue)
can be used to replace the
existing state with newValue
. The current state can also be transformed by
providing a transformation function to State.modify(transformFn)
.
Once a State
instance is defined, an initial seed state can be provided to
either the eval
or exec
methods to evaluate the computation and return the
result of the computation or the final state, respectively. Alternatively, the
run
method can be called to return both the result and the final state within
a Tuple
instance.
// An example deterministic pseudorandom number generator
// see: https://en.wikipedia.org/wiki/Linear_congruential_generator
// type RNG a = State Integer a
// rng :: RNG Float
const rng = State.get.chain(seed => {
const newSeed = (seed * 1103515245 + 12345) & 0x7FFFFFFF;
const randVal = (newSeed >>> 16) / 0x7FFF;
return State.put(newSeed).map(_ => randVal);
});
rng.eval(42); // From initial seed of 42: 0.5823236793115024
rng.eval(42); // Repeating produces the same value: 0.5823236793115024
rng.exec(42); // `exec` returns the next seed: 1250496027
rng.eval(1250496027); // A different seed: 0.5198217719046602
// Chain together to pass the new seed to the next RNG
// pair :: RNG a -> RNG (Tuple a a)
const pair = rng => rng.chain(a => rng.chain(b => State.of(Tuple(a, b))));
pair(rng).eval(42); // Tuple(0.5823236793115024, 0.5198217719046602)
// Map to produce transformed random values from 1 to 6
// rollDie :: RNG Integer
const rollDie = rng.map(n => Math.ceil(n * 6));
// rollDice :: RNG (Tuple Integer Integer)
const rollDice = pair(rollDie);
rollDice.eval(123); // Tuple(2, 5)
:: (s -> Identity (Tuple a s)) -> State s a
Constructs a State
instance that represent a pure computation from some state
to a new state and a result. Note this constructor requires the given function
to return an Identity
instance. It is generally recommended to use the static
properties and methods provided on the State
object rather than using this
constructor.
:: Monad m => { of :: a -> m a } -> (s -> m (Tuple a s)) -> StateT s m a
Constructs a StateT
instance that represent a computation from some state to a
new state and a result in the context of some other monad. It is generally
recommended to use the static properties and methods provided on the State
object rather than using this constructor.
:: State s s
A static State
instance that retrieves the current state.
:: Monad m => StateT s m s
A static StateT
instance that retrieves the current state.
:: (s -> a) -> State s a
Returns a State
instance the retrieves the current state transformed by the
given function.
:: Monad m => (s -> a) -> StateT s m a
Returns a State
instance the retrieves the current state transformed by the
given function.
:: s -> State s a
Returns a State
instance the stores the provided state.
:: Monad m => s -> StateT s m a
Returns a StateT
instance the stores the provided state
:: (s -> s) -> State s a
Returns a State
instance the modifies the stored state with the provided
function.
:: Monad m => (s -> s) -> StateT s m a
Returns a StateT
instance the modifies the stored state with the provided
function.
:: a -> State s a
Returns a State
instance that will evaluate to the provided value.
:: Monad m => a -> StateT s m a
Returns a StateT
instance that will evaluate to the provided value.
:: Monad m => m a -> StateT s m a
Lifts the given monad into a StateT
instance.
:: State s a ~> s -> Tuple a s
Runs the State
instance, seeded by the provided value and returns the final
state along with the result in a Tuple
.
:: Monad m => StateT s m a ~> s -> m Tuple(a, s)
Runs the StateT
instance, seeded by the provided value and returns the final
state along with the result in a Tuple
within the underlying monad type of the
transformer.
:: State s a ~> s -> a
Runs the State
instance, seeded by the provided value and returns the result.
:: Monad m => StateT s m a ~> s -> m a
Runs the StateT
instance, seeded by the provided value and returns the result
in the context of the underlying monad type of the transformer.
:: State s a ~> s -> s
Runs the State
instance, seeded by the provided value and returns the final
state.
:: Monad m => StateT s m a ~> s -> m s
Runs the StateT
instance, seeded by the provided value and returns the final
state in the context of the underlying monad type of the transformer.
:: State s a ~> (a -> b) -> State s b
Transforms the eventual result of the State
instance with the provided
function.
:: Monad m => StateT s m a ~> (a -> b) -> StateT s m b
Transforms the eventual result of the StateT
instance with the provided
function.
:: State s (a -> b) ~> State s a -> State s b
Applies the resulting function of this State
instance to the result of the
provided State
instance to produce a new State
instance.
:: Monad m => StateT s m (a -> b) ~> StateT s m a -> StateT s m b
Applies the resulting function of this StateT
instance to the result of the
provided StateT
instance to produce a new StateT
instance.
:: State s a ~> (a -> State s b) -> State s b
Creates a new State
instance by applying the given function to the result of
this State
instance.
:: StateT s m a ~> (a -> StateT s m b) -> StateT s m b
Creates a new StateT
instance by applying the given function to the result of
this StateT
instance.