Hi I am new to Scala and trying to call a higher order function sum_of from main class.I am getting "Cannot resolve reference sumOf with such signature error".
object SumOf {
def main(args: Array[String]) {
val y = sumOf(x=>x ,4,5)
println(y)
}
def sumOf(f: Int => Int)(a: Int, b: Int): Int = {
def loop(a: Int, acc: Int): Int =
if (a > b) acc
else loop(a + 1, f(a) + acc)
loop(a, 0)
}
}
sumOf is a curried function so it takes two arguments in the form of sumOf(x => x)(4,5) which is different from sumOf(x => x, 4,5). This is the reason you are getting an error.
Further, you can call it with only one argument sumOf(x => x) _ which returns another function that takes the second argument
(Int, Int) => Int = <function2> and return a function. This is more commonly known as partial function application.
Your sumOf method has two argument lists, and needs to be called with two argument lists.
val y = sumOf(x => x)(4, 5)
You can think of sumOf as a function which takes an Int => Int and returns a new function, which takes two Ints to return an Int.
Related
I am trying to create a function that receives a basic curried adder function with 2 parameters and returns uncurried adder function, and vice versa for the currying function(receives uncurried-returns curried) in scala. I am having a hard time figuring the return types of curried functions , can anyone help out?
def adderCurried(a: Int)(b: Int): Int = a + b
//define a function that returns uncurried version of this function:
val adderUncurried = toAdderUncurried(adderCurried)
adderUncurried(5,6) // returns 11
def adder(a: Int, b: Int): Int = a + b
//define a function that returns curried version of this function:
val adderCurried = toAdderCurried(adder)
adderCurried(5,6) // returns 11
Part of the problem is that you are not calling the curried function correctly:
adderCurried(5,6) // too many arguments (found 2, expected 1)
It should be called in a way that matches the declaration:
def adderCurried(a: Int)(b: Int)
adderCurried(5)(6)
This gives the clue that there are actually two function invocations here. The first invocation (5) returns a function that when called with (6) gives the answer. That second function must take an Int and return an Int so it is Int => Int, and this must be what is returned by adderCurried(5).
So adderCurried takes an Int and returns Int => Int so the type is
Int => (Int => Int)
or just
Int => Int => Int
You can check this as follows:
val check: Int => Int => Int = adderCurried // OK
You should be able to create the signatures for toAdderCurried and toAdderUncurried based on these types.
The toAdderUncurried function will be like this.
def toAdderUncurried(f: Int => Int => Int): (Int, Int) => Int = (x, y) => f(x)(y)
You can call it like this.
toAdderUncurried(adderCurried)(x, y)
And the curry function will be like this.
def curry(f: (Int, Int) => Int): Int => Int => Int = x => y => f(x, y)
you can call it like this
curry(toAdderUncurried(adderCurried))(x)(y)
Let me add Tim answer. Right here you have 2 options of your adder function:
curried type Curried = (Int => Int => Int)
and uncurried type Uncurried = (Int, Int) => Int
and your signatures of converting functions should looks like:
def toAdderUncurried(adderCurried: Curried): Uncurried = ???
def toAdderCurried(adderUncurried: Uncurried): Curried = ???
So i got the following function after some trial and error and research in our Textbook i could come up with a solution.
def prodC1(f : Int => Int) : (Int, Int) => Int = {
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
prodA1 // Why do i need this line here
}
If I don't put that there i get a Type mismatch, could someone elaborate/explain the requirement for this Line?
So there are a lot of things which you need to know to actually understand the answer to this.
In Scala any def is a method which is nothing more than one of the members of some object. methods are not first class members in Scala which also means that methods can not exist on their own.
In Scala, the value of anything needs to be an expression. Meaning the RHS for a def needs to be an expression like def abc = some-expression. Examples of expression are 1, 1 + 1, "xyz", anotherMethodCallWhichWillReturnAnExpression() etc.
And something like def abc = xxxxxx is not an expression in Scala language definition. And hence you can not do,
def prodC1(f : Int => Int) : (Int, Int) => Int = {
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
}
Now, when you are adding that extra line with prodA1, you are telling Scala to return this prodA1 which you just define. But remember prodA1 is just a method and hence can not exist on its own and hence can not actually be returned.
But functions are first class members in Scala (represented as instances of one of the various FunctionX classes) and hence can be returned.
In this case Scala will intelligently lift this method to become a function of type (Int, Int) => Int. This is called eta-expansion.
To understand things more in detail. You can open the Scala console and try the following.
scala> val s = "abc"
// s: String = abc
scala> val i = 10
// i: Int = 10
scala> def prodA1(a : Int, b : Int) : Int = if (a > b) 1 else a * prodA1(a+1, b)
// prodA1: (a: Int, b: Int)Int
Notice the difference between the output of Scala console for actual values and def. Now, if I try to use prodA1 as value of a val, I will get following error.
scala> val x = prodA1
// <console>:12: error: missing argument list for method prodA1
// Unapplied methods are only converted to functions when a function type is expected.
// You can make this conversion explicit by writing `prodA1 _` or `prodA1(_,_)` instead of `prodA1`.
// val x = prodA1
Scala is telling you that you can explicitly convert method to function by using a _. Lets try that.
scala> val x = prodA1 _
// x: (Int, Int) => Int = $$Lambda$1077/293669143#13278a41
Now x is a function of type (Int, Int) => Int.
Also, that first line Unapplied methods are only converted to functions when a function type is expected. is telling you about what actually happened in your case.
Since prodC1 was expected to return a function of type (Int, Int) => Int and you provided prodA1, Scala used eta-expansion to automatically convert your method to function.
Let's have a look at your return type.
def prodC1(f : Int => Int) : (Int, Int) => Int = {
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
prodA1 // Why do i need this line here
}
your return type is
(Int, Int) => Int
that is scala sugar for a Function2[Int, Int, Int]
where the first param is the type to the first param, the second param is the type for the second param and the last is the type for the return param
The return instance needs to be a function
prodA1 conforms to this type, meaning it is allowed to be returned.
Your function needs to return an instance of (Int, Int) => Int.
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
Creates a function of type (Int, Int) => Int with name prodA1 but the return type of defining an inner function does not create an instance of anything so the return type of the function is Unit.
Therefore you need to return the prodA1 which has the correct type..
I'm learning nested functions in Scala and here is some code I'm having trouble with
object Main extends App {
val fac = (x: Int) => {
val factorial: (Int, Int) => Int = (x, accum) => if (x == 1) accum else factorial(x-1, accum*x)
factorial(x,1)
}
println(fac(3))
}
the compiler gives this error:
forward reference extends over definition of value factorial
val factorial: (Int, Int) => Int = (x, accum) => if (x == 1) accum else factorial(x-1, accum*x)**
what am I doing wrong?
You should declare factorial using def and not val:
Using val means it's a value, evaluated once, at declaration; Therefore, it's easy to see why the compiler can't use that definition while evaluating it
Using def means it's a method, evaluated separately for every call, therefore supporting referencing itself within the definition (recursion)
Perhaps a less-confusing way to write this would be to declare this method as a method that expects arguments, instead of a method that returns a function which expects these arguments:
val fac = (x: Int) => {
def factorial(x: Int, accum: Int): Int = if (x == 1) accum else factorial(x-1, accum*x)
factorial(x,1)
}
In the following code:
def product(f: Int => Int)(a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f)(a + 1, b)
The parameters a and b are passed to the inner function, but you could write exactly the same function definition like so:
def product(f: Int => Int, a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f, a + 1, b)
So what is the purpose of separating the parameters? In other words, why do this:
(f: Int => Int)(a:Int, b:Int)
when you can more clearly write:
(f: Int => Int, a:Int, b:Int)
Another feature of multiple parameters lists is partial application:
def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c
val g: Int => Int => Int = sum3(10) _
val h: Int => Int = g(20)
val r: Int = h(30) // 10 + 20 + 30 = 60
You can partially apply a function and obtain another function which is equivalent to the original one but with one of the arguments fixed. _ after sum3(10) is needed because sum3 is a method, not a function, and _ converts methods to functions.
This is very useful when you are using higher-order functions:
def adder(x: Int)(y: Int) = x + y
Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14)
When partially applied method/function is used as an argument of a higher-order call, _ is not needed, and the syntax becomes very succinct.
Another use case of this feature is that if you want to create a control structure that looks like it's built into Scala programming language itself.
For example, I could write an control structure named times which help me execute the code block exactly n times by the following method definition:
// since block is call by name, it will not be evaluate when you call it.
def times(n: Int)(block: => Any): Unit = {
for (i <- 0 until n) {
block // evaluate(execute) block
}
}
// Now I can use the times method like a control structure
times(5) {
println("Hello World");
}
It depends whether there is implicit parameter (which can't be properly mixed with plain ones)...
def foo(i: Int)(implicit p: P): Foo
... and the way you want to call it ...
def foo1(a: Int)(b: Int => Boolean): Boolean
foo1(9) { i => false }
def foo2(a: Int, b: Int => Boolean): Boolean
foo2(9, { i => false })
Based on below examples of defining functions what is the best use of 2 and 3 in different scenarios?
def sum(x: Int, y: Int): Int = { x+y }
This is a function definition with arguments, return type and function body
val sum = (x: Int, y: Int) => { x+y }
This seems like an assignment of lambda function to a variable, why return type is never defined here?
val sum: (Int, Int) => Int = (x,y) => { x+y }
This is defining a function as a type?
I don't understand how this works!
All 3 functions when invoked will yield the same result:
scala> sum(1,2)
Int = 3
def sum(x: Int, y: Int): Int = { x+y }
This is a function definition with arguments, return type and function body
This is not a function definition. This is a method definition. Functions and methods are fundamentally different. Functions are objects, methods are not. (Methods belong to objects.) Methods can be polymorphic, functions can't.
val sum = (x: Int, y: Int) => { x+y }
This seems like an assignment of lambda function to a variable, why return type is never defined here?
Are you asking why the type of sum isn't declared or why the return type of the function literal isn't declared? The return type of the function literal isn't declared because there is no way in the syntax to do so. You simply cannot declare the return type of a function literal, it is always inferred. The type of sum isn't declared because it is not necessary: it can be inferred to be the same as the type of the function literal, i.e. Function2[Int, Int, Int].
Think val foo = "Hello".
val sum: (Int, Int) => Int = (x,y) => { x+y }
This is defining a function as a type?
No. This is the exact same thing as 2., except that here the type of sum is explicitly declared (as (Int, Int) => Int which is syntactic sugar for Function[Int, Int, Int]) instead of inferred. Since the type of sum is known, you can leave off the types of the function parameters, because they can be inferred from the context.
Think val foo: String = "Hello".
In line 2, scala compiler inferences type of lambda function.
val sum = (x: Int, y: Int) => { x + y }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function value
x and y are type of Int, thus x + y is a Int type. In this case, type of sum is (Int, Int) => Int.
In line 3, it shows the type of sum - (Int, Int) => Int. sum indicates a function same with line 2.
val sum: (Int, Int) => Int = (x,y) => { x+y }
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
type function value
Right side of = is function signature and body. It receives two arguments called x and y. Its body is x + y.
Shortly, line 2 and line 3 are equivalent. Line 2 has no type of function value, but scala can inference its type. Line 3 has type of function value explicitly, and omits argument type of signature of function value.
this is about the difference between method and function. The useful link to show the difference is http://java.dzone.com/articles/revealing-scala-magician%E2%80%99s
I think in the 3rd way, you can understand it like a type T = (Int, Int) => Int and then do this : val sum: T = (x,y) => { x+y }
another thing is that if remove input arguments, method and function is different.
def sum: Int = { 3 } //call sum, get 3
val sum: () => Int = () => { 3 } //call sum, return a function, need to call sum() to get 3