Implementing flatMap () for state transition

Exercise 6.8, Chiusano and Bjarnason, Functional Programming in Scala, p. 87 asks how flatMap () can be implemented for the following trait:

trait RNG {
  def nextInt: (Int, RNG)
}

type Rand[+A] = RNG => (A, RNG)

      

The answer key gives the following solution:

def flatMap[A,B](f: Rand[A])(g: A => Rand[B]): Rand[B] =
rng => {
  val (a, r1) = f(rng)
  g(a)(r1) // We pass the new state along
}

      

Stackoverflow provides many answers to flatMap () / monad questions, but none of them answered my questions regarding the next line of code for me.

I don't understand the syntax of the line

g(a)(r1)

      

(1) I don't understand how g (a) (r1) is evaluated. What syntactic function does (r1) serve? The string doesn't illustrate currying, I don't believe it, since g only takes one argument: A. (2) If g (a) already returns type Rand [B], then why doesn't the string end here? (3) What is the relationship between Rand [B] returned by g (a) and the second set of parentheses: (r1)? (4) if the return type of this implementation of flatMap () is Rand [B], which is RNG => (A, RNG), how are the parentheses to the right of the arrow enclosed? If I had to guess, I would say they are generated by the score (r1), but I don't really understand this code given my questions 1 through 3.

+3


source to share


1 answer


Remember that we are calling f

also g

inside the new anonymous function, as shown in the line

rng => { ... }

      

g

returns a Rand[B]

when given A

, so g(a)

evaluates the function from RNG

to (A, RNG)

.



So, g(a)

returns a function expecting as an argument RNG

, we can call this with ours r1

, which is of type RNG

.

Call result (B, RNG)

. Now, since the signature flatMap

expects you to return Rand[B]

which is the same as RNG => (B, RNG)

, and return (B, RNG)

inside our function, it matches the signature exactly.

+3


source







All Articles