Module state

Pythonic FP - State Monad

Handling state functionally.

##### class State - Classic FP State Monad

A pure FP immutable implementation for the State Monad.

  • translated to Python from the book “Functional Programming in Scala”

    • authors Chiusana & Bjarnason

    • run “action” returns a tuple (a, s) reversed to the type State[S, A]

      • the standard convention seen in the FP community

      • another “factoid” to remember

  • choose the name bind instead of flatmap

    • the flatmap name is misleading for non-container-like monads

    • flatmap name too long, bind shorter to type

      • without “do-notation”, code tends to march to the right

  • typing for the modify class method may be a bit suspect

class pythonic_fp.fptools.state.State(run)

Data structure generating values while propagating changes of state.

  • class State represents neither a state nor (value, state) pair

    • it wraps a transformation old_state -> (value, new_state)

    • the run method is this wrapped transformation

    • bind is just state propagating function composition

Parameters:

run (Callable[[TypeVar(S)], tuple[TypeVar(A), TypeVar(S)]])

bind(g)

Perform function composition while propagating state.

Parameters:

g (Callable[[TypeVar(A)], State[TypeVar(S), TypeVar(B)]])

Return type:

State[TypeVar(S), TypeVar(B)]

both(rb)

Return a tuple of two state actions.

Parameters:

rb (State[TypeVar(S), TypeVar(B)])

Return type:

State[TypeVar(S), tuple[TypeVar(A), TypeVar(B)]]

eval(init)

Evaluate the Monad via passing an initial state.

Parameters:

init (TypeVar(S))

Return type:

TypeVar(A)

static get()

Set run action to return the current state

  • the current state is propagated unchanged

  • current value now set to current state

  • will need type annotation

Return type:

State[TypeVar(ST), TypeVar(ST)]

map(f)

Map a function over a run action.

Parameters:

f (Callable[[TypeVar(A)], TypeVar(B)])

Return type:

State[TypeVar(S), TypeVar(B)]

map2(sb, f)

Map a function of two variables over two state actions.

Parameters:
  • sb (State[TypeVar(S), TypeVar(B)])

  • f (Callable[[TypeVar(A), TypeVar(B)], TypeVar(C)])

Return type:

State[TypeVar(S), TypeVar(C)]

static modify(f)

Modify previous state.

  • like put, but modify previous state via f

  • will need type annotation

    • mypy has no “a priori” way to know what ST is

Parameters:

f (Callable[[TypeVar(ST)], TypeVar(ST)])

Return type:

State[TypeVar(ST), tuple]

static put(s)

Manually insert a state.

THe run action.

  • ignores previous state and swaps in a new state

  • assigns a canonically meaningless value to current value

Parameters:

s (TypeVar(ST))

Return type:

State[TypeVar(ST), tuple]

static sequence(sas)

Combine a list of state actions into a state action of a list.

  • all state actions must be of the same type

  • run method evaluates list front to back

Parameters:

sas (list[State[TypeVar(ST), TypeVar(AA)]])

Return type:

State[TypeVar(ST), list[TypeVar(AA)]]

static unit(b)

Create a State action returning the given value.

Parameters:

b (TypeVar(B))

Return type:

State[TypeVar(ST), TypeVar(B)]