How does this Scala function work? - scala

def flatMap[A,B](f: Rand[A])(g: A => Rand[B]): Rand[B] =rng => {
val (a, r1) = f(rng)
g(a)(r1)
}
I am confused by g(a)(r1) because g is supposed to take only one argument, so why r1?

I don't exactly know the Rand[A] structure, so this is partially guessing. What you are returning in this function is a Rand[B] and when you implement the function you start of with defining an argument rng of an anonymous function. This tells me that Rand is probably some kind of function itself.
In the second line (val (a, r1) = f(rng)) you apply the value rng to the instance f: Rand[A]. In the resulting tuple, a has type A.
Note with this that f(rng) is equal to explicitly calling apply: f.apply(rng).
You can use the value a to get a Rand[B] by applying this value to the function g. So, val rb: Rand[B] = g(a) (or g.apply(a)).
Now, you don't want to return an instance of Rand[B] in this anonymous function! Instead you need to apply the previous result r1 to this instance rb. So, you get rb(r1) or rb.apply(r1). Substituting rb with g(a) or g.apply(a) gives you g(a)(r1) or g.apply(a).apply(r1).
To summarize, as you said, g is supposed to only take one argument, which results in an instance of Rand[B], but that is not the expected return type here. You need to apply the result of the previous computation to this new computation to get the expected result.

Related

How reduceLeft works on sequence of Functions returning Future

This might be a naive question and I am sorry for that. I am studying Scala Futures and stumbled on below code:
object Main extends App {
def await[T](f: Future[T]) = Await.result(f, 10.seconds)
def f(n: Int): Future[Int] = Future {n + 1}
def g(n: Int): Future[Int] = Future {n * 2}
def h(n: Int): Future[Int] = Future {n - 1}
def doAllInOrder[T](f: (T => Future[T])*): T => Future[T] = {
f.reduceLeft((a,b) => x => a(x).flatMap(y => b(y)))
}
println(await(doAllInOrder(f, g, h)(10))) // 21
}
I know how reduceLeft works when it is applied on Collections. But in the above example, as I understand, in the first pass of reduceLeft value x i.e. 10 is applied to Function a and the result is applied to Function b using flatMap which eventually return Future[Int] (say, I call it result). In the next pass of reduceLeft the result and Function h has to be used, but here is I am troubled.
The result is actually an already executed Future, but the reduceLeft next pass expects a Function which returns a Future[Int].Then how it is working?
Another thing I am not able to understand how each pass sending its result to next pass of reduceLeft, i.e. how x is getting it's value in subsequent passes.
Though both of my confusions are interrelated and a good explanation may help clear my doubt.
Thanks in advance.
You have to think about reduceLeft to be independent from Future execution. reduceLeft creates a new function by combining two given ones and that's it.
reduceLeft is applied to a Seq of T => Future[T]. So, it's just simple iteration from left to right over sequence of functions taking first and second elements and reducing it to one single value, reducing this value with the 3rd element and so on. Eventually, having just two element left that are reduced to a single one.
The result of reduceLeft has to be of the same type as the type of elements in the collection. In your case, it's function T => Future[T].
Let's understand what (a,b) => x => a(x).flatMap(y => b(y)) is doing
This means the following. Given functions a and b, create a function that combines function a with b. Mathematically it's c(x)=b(a(x)).
Now, a and b are functions returning futures. And futures can be chained with the help of map/flatMap methods.
You should read x => a(x).flatMap(y => b(y)) as
Given an input x, apply function a(x), this results in a Future, when this future is completed, take result y and apply function b(y), this results in a new Future. This is the result of function c.
Note: value x is Int at all times. It is the input parameter for your new reduced function.
If it's still not clear, let's address the points of confusions
The result is actually an already executed Future.
No future is guaranteed to be executed at any point here. map and flatMap are non blocking operation and it applies functions to a Future. The result of this application is still a Future.
Another thing I am not able to understand how each pass sending its
result to next pass of reduceLeft, i.e. how x is getting it's value in
subsequent passes.
This is easier to understand when just having integers in a collection. Given following code
Seq(1, 2, 5, 10).reduceLeft(_ - _)
It will take 1, 2 and apply - function, this will result in -1. It will then combine -1 and 5 resulting in -6. And finally, -6 with 10 resulting in -16.

Implementation of flatMap() for State transition

Exercise 6.8, Chiusano and Bjarnason, Functional Programming in Scala, p. 87 asks how one might implement flatMap() 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 which for me answered my questions regarding the next to last line of code.
I do not understand the syntax of the line
g(a)(r1)
(1) I do not understand how g(a)(r1) evaluates. What syntactic function is served by (r1)? The line does not exemplify currying, I do not believe, since g takes only one argument: A.
(2) If g(a) will already return the type Rand[B], then why does not the line end here?
(3) what is the relation between the 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 equal to RNG => (A, RNG), how are the enclosing parentheses to the right of the arrow generated? If I had to guess I would say they are generated by the evaluation, (r1), but I do not really understand this code given my questions 1 through 3.
Remember that we're calling f and g inside a new anonymous function, as indicated by the line
rng => { ... }
g returns a Rand[B] when given an A, so g(a) evaluates to a function from RNG to (A, RNG).
So g(a) returns a function expecting an RNG as its argument, we can then call this with our r1, which is of type RNG.
The result of the call is (B, RNG). Now since the flatMap signature expects you to return a Rand[B] which is the same as RNG => (B, RNG) and we return (B, RNG) inside our function, it exactly matches the signature.

Difference between f(a,b) and f(a)(b) in Scala

I am very very new to Scala. I am reading a book called functional programming in scala by Paul Chiusano and Rúnar Bjarnason. So far I am finding it interesting. I see a solution for curry and uncurry
def curry[A,B,C](f: (A, B) => C): A => (B => C)= {
a => b => f(a,b)
}
def uncurry[A,B,C](f: A => B => C): (A, B) => C = {
(a,b) => f(a)(b)
}
In Curry I understand f(a,b) which results in value of type C but in uncurry I do not understand f(a)(b). Can anyone please tell me how to read f(a)(b) or how is this resulting to a type of C or please refer me some online material that can explain this to me?
Thanks for your help.
Basically the return type of f(a) is a function of type B => C lets call this result g.
If you then call g(b) you obtain a value of type C.
f(a)(b) can be expanded to f.apply(a).apply(b)
In the uncurry method you take a so-called "curried" function, meaning that instead of having a function that evaluates n arguments, you have n functions evaluating one argument, each returning a new function until you evaluate the final one.
Currying without a specific support from the language mean you have to do something like this:
// curriedSum is a function that takes an integer,
// which returns a function that takes an integer
// and returns the sum of the two
def curriedSum(a: Int): Int => Int =
b => a + b
Scala however provides further support for currying, allowing you to write this:
def curriedSum(a: Int)(b: Int): Int = a + b
In both cases, you can partially apply curriedSum, getting a function that takes an integer and sums it to the number you passed in originally, like this:
val sumTwo: Int => Int = curriedSum(2)
val four = sumTwo(2) // four equals 4
Let's go back to your case: as we mentioned, uncurry takes a curried function and turns it into a regular function, meaning that
f(a)(b)
can read as: "apply parameter a to the function f, then take the resulting function and apply the parameter b to it".
In case if somebody is looking for an explanation. This link explains it better
def add(x:Int, y:Int) = x + y
add(1, 2) // 3
add(7, 3) // 10
After currying
def add(x:Int) = (y:Int) => x + y
add(1)(2) // 3
add(7)(3) // 10
In the first sample, the add method takes two parameters and returns the result of adding the two. The second sample redefines the add method so that it takes only a single Int as a parameter and returns a functional (closure) as a result. Our driver code then calls this functional, passing the second “parameter”. This functional computes the value and returns the final result.

A variable used in its own definition?

An infinite stream:
val ones: Stream[Int] = Stream.cons(1, ones)
How is it possible for a value to be used in its own declaration? It seems this should produce a compiler error, yet it works.
It's not always a recursive definition. This actually works and produces 1:
val a : Int = a + 1
println(a)
variable a is created when you type val a: Int, so you can use it in the definition. Int is initialized to 0 by default. A class will be null.
As #Chris pointed out, Stream accepts => Stream[A] so a bit another rules are applied, but I wanted to explain general case. The idea is still the same, but the variable is passed by-name, so this makes the computation recursive. Given that it is passed by name, it is executed lazily. Stream computes each element one-by-one, so it calls ones each time it needs next element, resulting in the same element being produces once again. This works:
val ones: Stream[Int] = Stream.cons(1, ones)
println((ones take 10).toList) // List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
Though you can make infinite stream easier: Stream.continually(1) Update As #SethTisue pointed out in the comments Stream.continually and Stream.cons are two completely different approaches, with very different results, because cons takes A when continually takes =>A, which means that continually recomputes each time the element and stores it in the memory, when cons can avoid storing it n times unless you convert it to the other structure like List. You should use continually only if you need to generate different values. See #SethTisue comment for details and examples.
But notice that you are required to specify the type, the same as with recursive functions.
And you can make the first example recursive:
lazy val b: Int = b + 1
println(b)
This will stackoverflow.
Look at the signature of Stream.cons.apply:
apply[A](hd: A, tl: ⇒ Stream[A]): Cons[A]
The ⇒ on the second parameter indicates that it has call-by-name semantics. Therefore your expression Stream.cons(1, ones) is not strictly evaluated; the argument ones does not need to be computed prior to being passed as an argument for tl.
The reason this does not produce a compiler error is because both Stream.cons and Cons are non-strict and lazily evaluate their second parameter.
ones can be used in it's own definition because the object cons has an apply method defined like this:
/** A stream consisting of a given first element and remaining elements
* #param hd The first element of the result stream
* #param tl The remaining elements of the result stream
*/
def apply[A](hd: A, tl: => Stream[A]) = new Cons(hd, tl)
And Cons is defined like this:
final class Cons[+A](hd: A, tl: => Stream[A]) extends Stream[A]
Notice that it's second parameter tl is passed by name (=> Stream[A]) rather than by value. In other words, the parameter tl is not evaluated until it is used in the function.
One advantage to using this technique is that you can compose complex expressions that may be only partially evaluated.

Function literal - Need help in understanding a code snippet

I'm basically new to functional programming and scala, and the following question might possibly look stupid.
val f = (a:Int) => a+1
In the above snippet, should I consider f to be a function or a variable? Coming from a C/C++ background, the first thought that occurs is that f is a variable that stores the return value of the anonymous function, but I think that's not the correct way to interpret it Any explanation would be really helpful.
(Some of the terminologies I used above might be wrong with respect to scala/functional programming, kindly bear with it)
Here, f is a variable that stores a function. It's really no different from saying any of the following:
val a = 4 // `a` is a variable storing an Int
val b = "hi" // `b` is a variable storing a String
val f = (a:Int) => a+1 // `f` is a variable storing a function
You can also confirm this with the REPL:
scala> val f = (a:Int) => a+1
f: Int => Int = <function1>
So this is telling you that f has the type Int => Int. Or in other words, f is a function that takes one argument, an Int, and returns an Int.
Since f is a variable, you can call methods on it or pass it as an argument to functions that expect its type:
a + 3 // here I'm calling the `+` method on `a`, which is an Int
f(3) // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a) // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f) // the `map` method expects a function from Int to Int, like `f`
Yes, like dhg said, f is a variable (that can't be changed) that stores a function.
However, there's a subtlety here:
... the first thought that occurs is that f is a variable that stores the
return value of the anonymous function
f actually stores the function, not the result. So you can give it different inputs, and get different outputs. So, you can use it like f(7) and then f(5). Functions in Scala are objects, so can be assigned to variables, passed as parameters, etc.
I recently posted about function literals, which may be helpful to you.
f is a value denoting a function literal.
In the statement, the right-hand-side is a function literal. The left-hand-side binds it to a name which is then called value (the val keyword is similar to let in LISP). Now the function is associated with the symbol f, so you can refer to that function by using this symbol f.
I disagree with the other answers which suggest that f should be called a variable. f is a value, because it is fixed to the right-hand-side term which is determined only once and cannot change. On the contrary a variable, introduced with var, allows you to re-assign values to a symbol:
var f = (i: Int) => i + 1
Where var begins a variable definition, f is the name or symbol of the variable, there could be an optional : ... defining type of the variable (if you leave that out, the type is automatically inferred from the assignment), and = ... defines the value initially assigned to the variable.
So when one says value, don't confuse this with a numeric constant, it is simply an entity that doesn't change. A function can be a value too, because f then always denotes this same identical function, even if you can feed that function with different arguments which yield different results.
Now with the var you can re-assign its right-hand-side:
f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4
Functional programming is all about avoiding variables (re-assignments).
It is also possible to define a function without assigning it at all (to a value or a variable). The following defines such a function and immediately calls it with argument 4:
{ i: Int => i + 1 } apply 4 // --> 5
although that is seldom useful as a statement per se, but you will see 'plain' functions often when calling a method that expects a function argument. For instance
val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 } // equivalent
s.map( _ + 1 ) // equivalent