I have a program as below, I can run it without problem using sum(x=>x)(1,2) for example.
What I don't understand is that why we can write sumF at the very end line, without parameters? I don't find explications about this.
Thanks.
def sum(f: Int => Int) : (Int, Int) => Int = {
def sumF(a:Int, b:Int) : Int = {
if (a > b) 0
else f(a) + sumF(a + 1, b)
}
sumF
}
The return value of the sum function is a function of type
(Int, Int) => Int
which is what sumF is
In Scala, if there is no return then the last expression is taken to be the return value. So, if the last expression is what you want to return, then you can omit the return keyword
What you are looking at is a higher order function. sum is a function that takes in a function f as its parameter and returns an arity 2 function that takes 2 ints and returns an Int (which is the exact type signature of sumF).
Related
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..
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.
I'm reading this scala book and a bit unsure on what this syntax translates to:
def bf: Int => Int => Int = i => v => i + v
bf is the name of the function.
after then colon is the function return type which is:
Int => Int => Int
I presume that the equal sign is the start of the function body, but not sure because then it has i => v => i + v.
Can someone clarify where each return type is and how to you break it down in your head so I can do the same :)
Short answer:
return type of the code can be read as Int => (Int => Int).
It is a function that takes single parameter of Int and returns a function that takes another Int parameter and returns Int.
If you are still getting confused, this is the longer way to write the same.
val bf: Int => (Int => Int) = (a:Int) => ((b: Int) => a + b)
|_________________| |____________________________|
type outer function
|________________|
inner func returned by the outer func
Long answer:
It is normally called curried function or function currying.
I assume You already noticed this though, This method originally trying to get sum of 2 Int values which is written as below.
val foo = (a: Int,b: Int) => a + b
any functions which takes multiple parameters can be transformed to nested single parameter functions a.k.a "curried function".
You may write it by your self just like your question code but You can call .curried to the method/function to get it as well.
val bf = foo.curried //bf is exactly the same thing as you wrote
This is usually used when you can't define both of the parameters at the same time so when you gets first value, make a function that (b: Int) => YOUR_FIRST_VALUE_ALREADY_DEFINED + b. and call it when you get second value.
How the curried function is used...
bf(4)(5) //9
val bar = bf(6) // (Int) => Int
bar(7) // 13
functional types are associate to the right.
for e.g.
Int => Int => Int is equivalent to Int => (Int => Int)
more details you can register and go through below lecture.
https://www.coursera.org/learn/progfun1/lecture/fOuQ9/lecture-2-2-currying
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
What exactly that declaration of method parameter means:
def myFunc(param: => Int) = param
What is meaning of => in upper definition?
This is so-called pass-by-name. It means you are passing a function that should return Int but is mostly used to implement lazy evaluation of parameters. It is somewhat similar to:
def myFunc(param: () => Int) = param
Here is an example. Consider an answer function returning some Int value:
def answer = { println("answer"); 40 }
And two functions, one taking Int and one taking Int by-name:
def eagerEval(x: Int) = { println("eager"); x; }
def lazyEval(x: => Int) = { println("lazy"); x; }
Now execute both of them using answer:
eagerEval(answer + 2)
> answer
> eager
lazyEval(answer + 2)
> lazy
> answer
The first case is obvious: before calling eagerEval() answer is evaluated and prints "answer" string. The second case is much more interesting. We are actually passing a function to lazyEval(). The lazyEval first prints "lazy" and evaluates the x parameter (actually, calls x function passed as a parameter).
See also
Scala Returning a void function with 0 parameters, ugly syntax?
Just to make sure there is an answer that uses the proper term: the Scala Language Specification uses the term call-by-name:
The type of a value parameter may be prefixed by =>, e.g. x: => T . The type of
such a parameter is then the parameterless method type => T . This indicates that
the corresponding argument is not evaluated at the point of function application, but
instead is evaluated at each use within the function. That is, the argument is
evaluated using call-by-name.
-- Section 4.6.1 of the Scala Language Specification
To add to Tomasz Nurkiewicz's answer above, the difference I encounter between () => Int and => Int is that the second allows calling with bare blocks:
scala> def myfunc(f : () => Int ) = println("Evaluated: " + f )
myfunc: (f: () => Int)Unit
scala> def myfunc2(f : => Int ) = println("Evaluated: " + f )
myfunc2: (f: => Int)Unit
scala> myfunc({1})
<console>:9: error: type mismatch;
found : Int(1)
required: () => Int
myfunc({1})
^
scala> myfunc2({1})
Evaluated: 1