fptools.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: Callable[[S], tuple[A, S]])

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

bind(g: Callable[[A], State[S, B]]) State[S, B]

Perform function composition while propagating state.

both(rb: State[S, B]) State[S, tuple[A, B]]

Return a tuple of two state actions.

eval(init: S) A

Evaluate the Monad via passing an initial state.

static get() State

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

map(f: Callable[[A], B]) State[S, B]

Map a function over a run action.

map2(sb: State[S, B], f: Callable[[A, B], C]) State[S, C]

Map a function of two variables over two state actions.

static modify(f: Callable[[ST], ST]) State[ST, tuple[()]]

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

static put(s: ST) State[ST, tuple[()]]

Manually insert a state.

THe run action.

  • ignores previous state and swaps in a new state

  • assigns a canonically meaningless value to current value

static sequence(sas: list[State]) State[ST, list[AA]]

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

static unit(b: B) State

Create a State action returning the given value.