zell
zell

Reputation: 10204

A typical scenario of using flatMap in State Monad?

I read the definition of a State Monad as follows, which includes a definition of flatMap. The literal definition of flatMap is clear to me, but what would be a typical use case of it?

trait State[S,A]{
  def run (initial:S):(S,A)
  def flatMap[B] (f:A=>State[S,B]):State[S,B] = 
    State{ s =>
      val (s1, a) = run(s)
      f(a).run(s1)
    }
}

object State{
  def apply[S,A](f:S => (S,A)):State[S,A] =
    new State[S,A] {
        def run(initial:S): (S,A) = f(initial) 
    }
}

Upvotes: 2

Views: 393

Answers (2)

Sagi
Sagi

Reputation: 9284

This quote is taken from wikibooks about state monad in haskell.

If you have programmed in any other language before, you likely wrote some functions that "kept state". For those new to the concept, a state is one or more variables that are required to perform some computation but are not among the arguments of the relevant function. Object-oriented languages like C++ make extensive use of state variables (in the form of member variables inside classes and objects). Procedural languages like C on the other hand typically use global variables declared outside the current scope to keep track of state.

In Haskell, however, such techniques are not as straightforward to apply. Doing so will require mutable variables which would mean that functions will have hidden dependencies, which is at odds with Haskell's functional purity. Fortunately, often it is possible to keep track of state in a functionally pure way. We do so by passing the state information from one function to the next, thus making the hidden dependencies explicit.

Basically its purpose is the to write purely functional programs that manipulate state, having the API compute the next state rather than actually mutate anything.

The most common examples for the state monad are:

  1. Generate random numbers.
  2. Building games
  3. Parsers
  4. Data Stuctures
  5. Any finite state machine program.

You can also check the cats page for the state monad

Note: There is an additional more complexed state monad which is called IndexedState monad, which basically gives you the option to change the state.

Upvotes: 2

Mario Galic
Mario Galic

Reputation: 48410

According to cats State monad documentation

The flatMap method on State[S, A] lets you use the result of one State in a subsequent State

It means we can have state transitions nicely lined up within a for-comprehension like so

val createRobot: State[Seed, Robot] =
  for {
    id <- nextLong
    sentient <- nextBoolean
    isCatherine <- nextBoolean
    name = if (isCatherine) "Catherine" else "Carlos"
    isReplicant <- nextBoolean
    model = if (isReplicant) "replicant" else "borg"
  } yield Robot(id, sentient, name, model)

In general, purpose of flatMap is chaining of monadic computations, so whatever monad we have we can stick it within a for-comprehension.

Upvotes: 3

Related Questions