monastic

A functional approach to stateful computations

Usage no npm install needed!

<script type="module">
  import monastic from 'https://cdn.skypack.dev/monastic';
</script>

README

Monastic

License: MIT Code Coverage

A state monad implementation compliant to Fantasy Land inspired by fantasy-states.

$ npm install --save monastic

State

State :: (s -⁠> {state :: s, value :: a}) -⁠> State s a

State type representative.

State.fantasy-land/of :: a -⁠> State s a

Fantasy Land compliant implementation of Of.

> evalState (null) (Z.of (State, 1))
1

run :: s -⁠> State s a -⁠> {state :: s, value :: a}

Evaluate a State instance with the given initial state and return both the internal state and value.

> run (1) (Z.of (State, 2))
{state: 1, value: 2}

modify :: (s -⁠> s) -⁠> State s Null

Creates a State instance which transforms its internal state using the given transformation function, and has a value of null.

> execState (1) (modify (s => s + 1))
2

Modify can be used inside chain to get a new State instance with the internal state transformed.

> execState (null) (
.   Z.chain (() => modify (s => s * 2), put (2))
. )
4

put :: s -⁠> State s Null

Creates a State instance which sets its internal state to the given value, and has a value of null.

> execState (1) (put (2))
2

get :: State s s

A State instance whose value is its internal state.

> evalState () (
.   Z.chain (() => get, put (1))
. )
1

evalState :: s -⁠> State s a -⁠> a

Evaluate a State instance with the given initial state and return the final value, discarding the final state.

> evalState () (Z.of (State, 1))
1

execState :: s -⁠> State s a -⁠> s

Evaluate a State instance with the given initial state and return the final state, discarding the final value.

> execState () (put (1))
1

State.fantasy-land/chainRec :: ((a -⁠> c, b -⁠> c, v) -⁠> State s c, v) -⁠> State s b

Fantasy Land compliant implementation of ChainRec.

> const f = (next, done, v) => Z.of (State, v > 10 ? done (v) : next (v + 1))

> evalState (null) (Z.chainRec (State, f, 1))
11

State.prototype.fantasy-land/chain :: State s a ~> (a -⁠> State s b) -⁠> State s b

Fantasy Land compliant implementation of Chain.

> evalState (null) (
.   Z.chain (v => Z.of (State, v + 1), Z.of (State, 1))
. )
2

State.prototype.fantasy-land/map :: State s a ~> (a -⁠> b) -⁠> State s b

Fantasy Land compliant implementation of Map.

> evalState (null) (
.   Z.map (x => x + 1, Z.of (State, 1))
. )
2

State.prototype.fantasy-land/ap :: State s a ~> State s (a -⁠> b) -⁠> State s b

Fantasy Land compliant implementation of Ap.

> evalState (null) (
.   Z.ap (Z.of (State, x => x + 1), Z.of (State, 1))
. )
2

StateT :: Monad m => m -⁠> StateT s m a

A state monad parametrised by the type m of the state to carry.

> import Maybe from 'sanctuary-maybe'

> const StateMaybe = StateT (Maybe)

> StateMaybe.evalState () (Z.of (StateMaybe, 42))
Z.of (Maybe, 42)

StateT

StateT(m).run :: s -⁠> StateT s m a -⁠> m s a

Evaluate a StateT(m) instance with the given initial state and return both the internal state and value wrapped in a monad.

> run (1) (Z.of (StateMaybe, 2))
Z.of (Maybe, {state: 1, value: 2})

StateT(m).fantasy-land/of :: Monad m => a -⁠> StateT s m a

Fantasy Land compliant implementation of Of.

> StateMaybe.evalState (null) (Z.of (StateMaybe, 1))
Z.of (Maybe, 1)

StateT(m).modify :: Monad m => (s -⁠> s) -⁠> StateT s m Null

Creates a StateT(m) instance which transforms its internal state using the given transformation function, and has a value of null.

> StateMaybe.execState (2) (StateMaybe.modify (x => x + 1))
Z.of (Maybe, 3)

StateT(m).put :: Monad m => s -⁠> StateT s m Null

Creates a StateT(m) instance which sets its internal state to the given value, and has a value of null.

> StateMaybe.execState (1) (StateMaybe.put (2))
Z.of (Maybe, 2)

StateT(m).get :: Monad m => StateT s m s

A StateT(m) instance whose value is its internal state.

> run () (
.   Z.chain (() => StateMaybe.get, StateMaybe.put (1))
. )
Z.of (Maybe, {state: 1, value: 1})

StateT(m).evalState :: Monad m => s -⁠> StateT s m a -⁠> m a

Evaluate a StateT(m) instance with the given initial state and return the final value wrapped in a monad, discarding the final state.

> StateMaybe.evalState () (Z.of (StateMaybe, 1))
Z.of (Maybe, 1)

StateT(m).execState :: Monad m => s -⁠> StateT s m a -⁠> m s

Evaluate a StateT(m) instance with the given initial state and return the final state wrapped in a monad, discarding the final value.

> StateMaybe.execState () (StateMaybe.put (1))
Z.of (Maybe, 1)

StateT(m).lift :: Monad m => Monad b -⁠> StateT s m b

Creates a StateT(m) instance and sets its value to the value wrapped in the given Monad.

> StateMaybe.evalState () (
.   StateMaybe.lift (Z.of (Maybe, 1))
. )
Z.of (Maybe, 1)

StateT(m).fantasy-land/chainRec :: ((a -⁠> c, b -⁠> c, v) -⁠> State s m c, v) -⁠> State s m b

Fantasy Land compliant implementation of ChainRec.

> const recf = (next, done, v) =>
.   Z.of (StateMaybe, v > 10 ? done (v) : next (v + 1));
> StateMaybe.evalState (null) (
.    Z.chainRec (StateMaybe, recf, 1)
. )
Z.of (Maybe, 11)

StateT(m).hoist :: Monad m => StateT s m a -⁠> (m a -⁠> m b) -⁠> StateT s m b

Creates a StateT(m) instance which transforms its internal value using the given transformation function.

> StateMaybe.evalState (null) (
.   StateMaybe.hoist (Z.of (StateMaybe, 1)) (x => Z.map (v => v + 1, x))
. )
Z.of (Maybe, 2)

StateT(m).prototype.fantasy-land/chain :: Monad m => StateT s m a ~> (a -⁠> StateT s m b) -⁠> StateT s m b

Fantasy Land compliant implementation of Chain.

> StateMaybe.evalState (null) (
.   Z.chain (v => Z.of (StateMaybe, v + 1), Z.of (StateMaybe, 1))
. )
Z.of (Maybe, 2)

StateT(m).prototype.fantasy-land/map :: Monad m => StateT s m a ~> (a -⁠> b) -⁠> StateT s m b

Fantasy Land compliant implementation of Map.

> StateMaybe.evalState (null) (
.   Z.map (x => x + 1, Z.of (StateMaybe, 1))
. )
Z.of (Maybe, 2)

StateT(m).prototype.fantasy-land/ap :: Monad m => State s m a ~> State s m (a -⁠> b) -⁠> State s m b

Fantasy Land compliant implementation of Ap.

> StateMaybe.evalState (null) (
.   Z.ap (Z.of (StateMaybe, x => x + 1), Z.of (StateMaybe, 1))
. )
Z.of (Maybe, 2)