Reputation: 3956
I have two functions
val mul3 = 3*(_: Double)
val pow2 = (x: Double) => x*x
What I don't understand how it works at all is this:
println((pow2.andThen[Double] _ )(mul3)(5))
1) I thought andThen
operates with results of the function to the left, but here it is [Double] _
- what is this? (I was expecting something like pow2 andThen mul3
)
2) Why is mul3
passed to pow2
if pow2
expects Double
? (mul3(pow2)
gives an error)
3) What is being passed to pow2
? Is it mul3
or 15?
4) What does .
mean?
Upvotes: 1
Views: 299
Reputation: 22850
Lets go step by step.
val mul3 = 3*(_: Double)
Is a Function from a Double to another Double. Thus, is type is Function1[Double, Double]
.
The same applies to:
val pow2 = (x: Double) => x*x
Now, remember that in Scala, everything is an object. And that there are not operators, only methods. So:
pow2.andThen[Double]
Is calling the andThen
on method on the Function1 class.
As you can see on the scaldoc, that method receives another function. Also, it is parametric in the return type of the second function, which determines the return type of the composed function that is returned.
So the [Double]
part is just specifying that type.
pow2.andThen[Double] _
Is using the underscore syntax to create another function.
The above line is equivalent to:
f => pow2.andThen[Double](f)
So, it is creating a function that takes another function as input, and returns another function. The resulting function will call pow2
first and then call the function passed as the argument.
Thus, it is of type Function1[Function1[Double, Double], Function[Double, Double]]
.
Then
(pow2.andThen[Double] _ )(mul3)
Is passing mul3
as the argument of that function, returning a final function (Function1[Double, Doule]
) that calls pow2
first and pass the result to mul3
.
Finally
(pow2.andThen[Double] _ )(mul3)(5)
Is calling the resulting function with 5
as is input.
After substitution, the code is equivalent to:
x => mul3(pow2(x))
x => 3 * (x * x)
5 => 3 * (x * x)
3 * (5 * 5)
75.0
Side note, IMHO, that code is very cryptic and far for what I would call idiomatic in Scala.
Upvotes: 1