Understanding Scala Currying - scala

I am following a course from coursera where this example appears in the lecture but when I try and run it, it throws an error as follows:
missing argument list for method mapReduce in object HelloWorld
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing mapReduce _ or mapReduce(_,_,_)(_,_) instead of mapReduce.
var doo = mapReduce(x => x,(x,y)=>x*y,0)
Below is the code that I want to execute.
def mapReduce(map: Int => Int, combine: (Int,Int)=>Int,
zero: Int)(a: Int,b: Int): Int = {
if (a>b) zero
else combine(map(a), mapReduce(map,combine,zero)(a+1,b))
}
var doo = mapReduce(x => x, (x,y)=>x*y, 0)
println(doo(1,4))

mapReduce wants two argument lists, but your are giving it one.
Try this:
val doo = mapReduce(x => x, (x,y) => x*y, 0) _
or equivalently,
val doo = mapReduce(identity, _*_, 0) _
The _ in the end stands for the second argument list. It tells the compiler that you want the suffixed value to be taken as a functional value rather than an expression to be evaluated.
You can also give compiler a hint to make the conversion happen automatically by explicitly declaring the expected type of the expession:
val doo: (Int, Int) => Int = mapReduce(identity, _*_, 0)
And don't use vars. They are evil. Just pretend, there is no such keyword in scala, until you learn enough of the language to be able to recognize the extremely rare cases when it is actually needed.

You have to define a undescore parameter in order to create a curried function. Like this:
scala> var doo = mapReduce(x => x, (x,y)=>x*y, 0) _
doo: (Int, Int) => Int = <function2>
scala> println(doo(1,4))
0

Related

Scala - Two functions sharing the second parameter list

I am new in Scala and I just came across a situation that I would like someone could explain me.
When watching a Martin Odersky's course I found the following script he uses to explain functions which return a function
val tolerance = 0.0001
def isCloseEnough(x : Double, y : Double) = abs((x - y)/ x) / x < tolerance
def fixedPoint(f : Double => Double)(firstGuess: Double) = {
def iterate(guess: Double): Double = {
val next = f(guess)
if(isCloseEnough(guess,next))next
else iterate(next)
}
iterate(firstGuess)
}
fixedPoint(x => 1 + x/2)(1)
def averageDamp(f: Double => Double)(x: Double) = (x + f(x))/2
def sqrt(x : Double) = fixedPoint(averageDamp(y => x/y))(1)
sqrt(2)
I understand perfectly how the scrip works, but I didn't expect this line:
fixedPoint(averageDamp(y => x/y))(1)
I know that thanks to Currying, Scala let us write functions with several parameter list. So the call to fixedPoint passing as parameter the result of avergaDamp and (1) is clear for me.
What I don't understand is how averageDamp uses the second parameter list of fixedPoint when it itself is inside the first parameter list. I though that would be a different scope, so I was expecting something like:
fixedPoint(averageDamp(y => x/y)(1))(1)
What is the property of Scala which allow us to implement the currying in this way? Is something similar to an implicit applied to a parameter list?
Thanks for your time
This is just how multiple parameter lists work: averageDamp(y => x/y) is equivalent to z => averageDamp(y => x/y)(z) and so its type is Double => Double.
If you wrote fixedPoint(averageDamp(y => x/y)(1))(1) as you expect, it would have a type mismatch because averageDamp(y => x/y)(1) has type Double and fixedPoint needs Double => Double.
Implicits aren't relevant here.
This line works because in the following expression:
fixedPoint(averageDamp(y => x/y))(1)
function "averageDamp(y => x/y)" is "passed by name" i.e. it will not be evaluated while passing to function "fixedPoint" but will be evaluated when it is called from inside "fixedPoint".
value "(1)" is just pass to argument "firstGuess" of "fixedPoint" which will be supplied to parameter "guess" inside the function definition in following expression:
val next = f(guess)

Scala partial application via underscore when composing function literals

I am composing function literals, though unlike most examples I've seen I'm starting with a multi-argument function that is then curried.
I have:
//types
case class Thing1(v: Double)
case class Thing2(v: Double)
case class Thing3(v: Double)
type Multiplier = Double
//functions
val f1 = (t: Thing1, m: Multiplier) => Thing2(m * t.v)
val f2 = (t: Thing2) => Thing3(t.v)
I want to compose f1 and f2 to get a combined function
Thing1 => (Multiplier => Thing3)
As expected, the following doesn't compile:
val fcomposed1 = f1.curried.andThen(f2) // does not compile
By experimentation, I was able to work out that the following does compile and has the right signature for fcomposed:
val fcomposed2 = f1.curried(_:Thing1).andThen(f2)
I've read various sources like What are all the uses of an underscore in Scala? and possibly relevant Why does Scala apply thunks automatically, sometimes? but unfortunately I still cannot work out exactly step-by-step what is happening here and why it works.
Furthermore, I would expect the above separated into two expressions to work identically to fcomposed2, however instead the second does not compile:
val f1partial = f1.curried(_:Thing1)
val fcomposed3 = f1partial.andThen(f2) // does not compile - same error as fcomposed1
Looks like f1partial returns the same signature as f1.curried, which makes me wonder further how the earlier fcomposed2 works.
Could someone please explain both behaviours step by step?
Here, the _ is acting as syntactical sugar for a lambda expression, but at a level you might not expect.
f1.curried has type Thing1 => Multiplier => Thing2
f1.curried(_:Thing1) is the same as { x: Thing1 => f1.curried(x) }. Since the result of f1.curried(x) has type Multiplier => Thing2, the final type of the whole expression is still Thing1 => Multiplier => Thing2. So it is not valid to call andThen(f2) on the result (f1partial) because the input type of function f2 (Thing2) is not the same as the output of the previous function (Multiplier => Thing2).
By contrast, f1.curried(_:Thing1).andThen(f2) expands to { x: Thing1 => f1.curried(x).andThen(f2) }. f1.curried(x) evaluates to type Multiplier => Thing2, like stated earlier, so you can call andThen(f2) on that, resulting in a Multiplier => Thing3. So then the entire expression evaluates to a Thing1 => Multiplier => Thing3
Perhaps it's more clear if you think about the differences between these two expressions:
val fcomposed1 = { x: Thing1 => f1.curried(x).andThen(f2) } // valid
val fcomposed2 = { x: Thing1 => f1.curried(x) }.andThen(f2) // error

How to use function with Any input

I have to define a second order function that takes as a parameter a function.
In my application, the input function may have any input type, but the output type has to be a specified one (suppose Int, it does not matter).
I define the second order function has:
def sof(f : (Any => Int) ) = {...}
Now, if I have a function f : Int => Int, and I call:
sof(f)
I get:
found : Int => Int
required: Any => Int
I guess I am misunderstanding the meaning of the Any type.
How can I make it work?
The parameters of functions in Scala are contravariant. That means that Int => Int is not a subtype of Any => Int, but vice-versa. Imagine the following: You pass a String to the Any => Int function (that is actually implemented by a Int => Int function). How would the Int => Int handle the String argument?
You shouldn't use Any there, but a type parameter such as:
def sof[A](f: A => Int) = {...}
However I don't think you can do much with that method. Probably you would want something like this:
def sof[A](a: A)(f: A => Int) = f(a)
// usage example
val x = sof("hello")(_.size * 2) // the result is 10
// you can also partially apply it to obtain other functions
val sizeDoubler: String => Int = sof(_)(_.size * 2)
val helloDoubleSize = sizeDoubler("hello") // the result is 10
This way you can pass any type to sof plus you'll have the compiler by your side to signal any strange behaviour. Using Any you lose this ability.
Final Note: In case the syntax I used to pass two parameters (the A value and the A => Int function) to a method looks strange to you that's called currying. If you Google it you'll find many good articles about it.

Writing tests to verify passing a function as argument in Scala

I have something like this:
def fnA(argA: Int, argB: Int, argC: Int): Seq[Int] = {
tryRequest {
...
}
}
def tryRequest[T](f: => T): T = {
try {
f
} catch {
...
}
}
I'm trying to figure out how to test this with Mockito/ScalaTest. I want to either make sure that 1. my return type is what I expect it to be (Seq[Int] when I call fnA), or 2. that I am passing in the right type to tryRequest when I'm calling it ((Int, Int, Int) => Seq[Int] when I call fnA). I've tried variations of:
exampleInstance.fnA(1, 2, 3)
there was one(exampleInstance).tryRequest(any)
but I always get something like
Argument(s) are different! Wanted:
exampleInstance.tryRequest(
($anonfun$apply$17) <function0>
);
Actual invocation has different arguments:
exampleInstance.tryRequest(
($anonfun$fnA$1) <function0>
);
Any ideas how I can accurately test this? Thanks!
It's not entirely clear what you're passing where - you seem to think you're passing a (Int, Int, Int) => Seq[Int] to tryRequest, but the definition of fnA you give isn't doing that (it's already taken the Int arguments before it calls tryRequest). But going by what you've written rather than the code:
It's generically impossible to compare functions for equality, and that syntax will "really" create an anonymous wrapper (do you really need the laziness of the => T given that you're passing a function in there anyway?), thus the failures. What you can do is confirm that the function that was passed to the inner call has some of the same properties as the function you already passed. I don't know the fancy syntax, but with an ordinary Java testing/mocking library I'd do something like:
val myCaptor = capture[=> ((Int, Int, Int) => Seq[Int])]
expect(exampleInstance.tryRequest(myCaptor.capture()))
exampleInstance.fnA({(a, b, c) => a + b + c})
val functionThatWasPassed = myCaptor.getValue()
assertThat(functionThatWasPassed(3, 4, 5)) isEqualTo 12
assertThat(functionThatWasPassed(-1, 0, 2)) isEqualTo 1

Specifying the lambda return type in Scala

Note: this is a theoretical question, I am not trying to fix anything, nor am I trying to achieve any effect for a practical purpose
When creating a lambda in Scala using the (arguments)=>expression syntax, can the return type be explicitly provided?
Lambdas are no different than methods on that they both are specified as expressions, but as far as I understand it, the return type of methods is defined easily with the def name(arguments): return type = expression syntax.
Consider this (illustrative) example:
def sequence(start: Int, next: Int=>Int): ()=>Int = {
var x: Int = start
//How can I denote that this function should return an integer?
() => {
var result: Int = x
x = next(x)
result
}
}
You can always declare the type of an expression by appending : and the type. So, for instance:
((x: Int) => x.toString): (Int => String)
This is useful if you, for instance, have a big complicated expression and you don't want to rely upon type inference to get the types straight.
{
if (foo(y)) x => Some(bar(x))
else x => None
}: (Int => Option[Bar])
// Without type ascription, need (x: Int)
But it's probably even clearer if you assign the result to a temporary variable with a specified type:
val fn: Int => Option[Bar] = {
if (foo(y)) x => Some(bar(x))
else _ => None
}
Let say you have this function:
def mulF(a: Int, b: Int): Long = {
a.toLong * b
}
The same function can be written as lambda with defined input and output types:
val mulLambda: (Int, Int) => Long = (x: Int, y: Int) => { x.toLong * y }
x => x:SomeType
Did not know the answer myself as I never had the need for it, but my gut feeling was that this will work. And trying it in a worksheet confirmed it.
Edit: I provided this answer before there was an example above. It is true that this is not needed in the concrete example. But in rare cases where you'd need it, the syntax I showed will work.