I'm new to scala, and I see this piece of code:
def sum(f: Int => Int)(a: Int, b: Int): Int = ...
I know that this sum function takes a function with 2 parameters(a and b) of type Ints.
Am I correct to say that:
The sum function takes a function, because i see (f: after def sum?
I'm a bit confused with the Int => Int syntax and the last :Int before =.
What does the Int on the left of the right arrow indicate?
Does the Int type on the right of the right arrow indicate:
the return value of the sum function?
or does it indicate the return value of the anonymous function
does the last :Int = indicate the return value of sum function is of type Int??
The sum method takes 3 parameters, split between two lists, and returns an Int. The first parameter list is for a function that takes an Int and returns an Int. That makes sum a higher-order function (in the loose sense of equating methods and functions). The colon means "of type".
It's significant to note that there is a different syntax for return values of functions and methods. This is because functions are values in Scala, and therefore their arguments and return types must be captured by a single type, and the => captures this. Methods are not values, and their parameter types and return types are notated separately. You may be able to gloss over this as a beginner, but I think it's worthwhile to explore the distinction.
Related
Find Square of an integer 'x'.
Without Placeholder
var square = (x:Int) => x*x
square(3) gives desired output 9.
With Placeholder var square = (_:Int)*(_:Int)
square(3) gives Error
Not enough arguments for method apply: (v1: Int, v2: Int)Int in trait Function2.
Unspecified value parameter v2.
Internally what is happening?
No, each occurrence of _ represents the next argument in the argument list for the function.
(_:Int)*(_:Int) is a function that takes two Int arguments and multiplies them.
I have a confusion between higher-order function and partially applied function. Can I say the partially applied function is Higher-order function because partially applied function also return function?
Partially applied function is the result of the process of partial application. This resulting function does not necessarily have to be higher-order, for example consider
val f: (Int, Int) => (Int) = (a, b) => a + b
val g: Int => Int = f(1, _) // g is partially applied function
Here function g is a partially applied function and yet it is first-order Int => Int. However the process of partial application itself is indeed a higher-order process as it takes a function and returns a function, similar to, perhaps, differential operator from calculus which also takes a function as input and returns a function as output.
As a side-note, currying and partial application are related but not identical.
Higher order function is the fact that you can pass one or multiple functions as parameters or have them as a result. Functions are the same as variables. whereas currying is when a function has multiple parameters and you precise only a few of them so you obtain a new function. So currying can be seen as an example of higher order function because you return a function when you use currying.
Currying example:
def plus(a :Int)(b: Int): Int = a + b
def plus5 = plus(5)
plus5 is a function and that's a kind of higher order function.
This question already has an answer here:
Can anyone explain how the symbol "=>" is used in Scala
(1 answer)
Closed 4 years ago.
I am new to scala and I confused little bit with = and =>, I don't know in which scenario exactly = used and => used.
#RamanMishra's comment is correct, however I would like to expand it a bit hopping it becomes more clear to you.
a = b means a is now equals to b (in the imperative meaning of the word, which is better understood as assignment).
It is used in many places, including when defining a function\method, for example
def sum(a: Int, b: Int): Int = a + b
The above statement can be readed as:
"We defined a function with name sum which takes two parameters (a & b) both of type Int and returns an Int. And its body\implementation is 'equals' to a + b".
a => b means, there is a function which takes a parameters list a and has a body b, it is used a couple of places, including anonymous functions and higher-order functions.
val anonymous: Int => Int = x => x + 1
The above statement can be readed as:
"We defined a value called anonymous, whose type is a function with one parameter of type Int and a return type Int, which is 'equals' to the 'anonymous' function which takes one parameter x (its type is inferred in by the context, in this type the explicit type signature before) and its body is x + 1"
def higherOrder(x: Int, f: Int => Int): Int = f(x)
The above statement can be readed as:
"There is a function (sum), which takes another function as a parameter (f), the later is a function of type Int to Int".
Edit
As #Aki suggested, the => is also used in pattern matching to separate the cases and the block of code to execute for each one.
def fact(n: Long): Long = n match {
case 0L => 1L
case n => n * fact(n - 1)
}
"This is somewhat similar to a parameter list => function body, as the above examples".
PS: This is a 101 Scala question, SO is not the best place for such questions, because there is probably enough resources on the internet - like this cheatsheet, or better places to ask - like the scala gitter channel.
I just wanted to clarify something about partially defined functions in Scala. I looked at the docs and it said the type of a partial function is PartialFunction[A,B], and I can define a partial function such as
val f: PartialFunction[Any, Int] = {...}
I was wondering, for the types A and B, is A a parameter, and B a return type? If I have multiple accepted types, do I use orElse to chain partial functions together?
In the set theoretic view of a function, if a function can map every value in the domain to a value in the range, we say that this function is a total function. There can be situations where a function cannot map some element(s) in the domain to the range; such functions are called partial functions.
Taking the example from the Scala docs for partial functions:
val isEven: PartialFunction[Int, String] = {
case x if x % 2 == 0 => x+" is even"
}
Here a partial function is defined since it is defined to only map an even integer to a string. So the input to the partial function is an integer and the output is a string.
val isOdd: PartialFunction[Int, String] = {
case x if x % 2 == 1 => x+" is odd"
}
isOdd is another partial function similarly defined as isEven but for odd numbers. Again, the input to the partial function is an integer and the output is a string.
If you have a list of numbers such as:
List(1,2,3,4,5)
and apply the isEven partial function on this list you will get as output
List(2 is even, 4 is even)
Notice that not all the elements in the original list have been mapped by the partial function. However, there may be situations where you want to apply another function in those cases where a partial function cannot map an element from the domain to the range. In this case we use orElse:
val numbers = sample map (isEven orElse isOdd)
And now you will get as output:
List(1 is odd, 2 is even, 3 is odd, 4 is even, 5 is odd)
If you are looking to set up a partial function that, in effect, takes multiple parameters, define the partial function over a tuple of the parameters you'll be feeding into it, eg:
val multiArgPartial: PartialFunction[(String, Long, Foo), Int] = {
case ("OK", _, Foo("bar", _)) => 0 // Use underscore to accept any value for a given parameter
}
and, of course, make sure you pass arguments to it as tuples.
In addition to other answers, if by "multiple accepted types" you mean that you want the same function accept e.g. String, Int and Boolean (and no other types), this is called "union types" and isn't supported in Scala currently (but is planned for the future, based on Dotty). The alternatives are:
Use the least common supertype (Any for the above case). This is what orElse chains will do.
Use a type like Either[String, Either[Int, Boolean]]. This is fine if you have two types, but becomes ugly quickly.
Encode union types as negation of intersection types.
w.r.t Currying in scala, partly I understood below sample code.
def product1(f:Int => Int )(a:Int, b:Int):Int = {
println()
if(a > b ) 1
else
f(a) * product1(f)(a+1, b)
}
product(x => x * x) (3, 4)
Out of it., I am bit confused with
product1(f)
in
product1(f)(a+1, b)
Just need explanation, what goes on here.... :( and how to pronounce verbally while explaining...
Thanks in advance..
product1 has two parameter lists. product1(f) is the application of f which is a function of kind Int => Int. If you were only to call product1(f) like so:
product1(f)
without the second parameter list, you'd get a so-called partially-applied function, i.e. a function which doesn't have all of its parameters bound (you'd still need to provide it with a and b)
Look at the parameter declaration:
f:Int => Int
f is a function that maps an Int to an Int -- it takes an Int as an argument and returns an Int. An example is given:
x => x * x
returns the square of its argument.
product1(x => x * x) (3, 4)
returns the product of f(3) .. f(4) = 3*3 * 4*4
BTW, this isn't really an example of currying, since all the arguments are given. Currying would be something like
val prodSquare = product1(x => x * x)
Then,
prodSquare(1, 5)
yields 1*1 * 2*2 * 3*3 * 4*4 * 5*5
For most idiomatic purposes I've seen, you may as well think of your function as having just one parameter list. Multiple parameter lists are used mostly for type inference purposes in generic functions, since type inference is done one parameter list at a time, rather than using Hindley-Milner/Algorithm W to infer the type of everything at once. Some other language features work on individual parameter lists, such as implicit parameters and implicit use of braces in place of parentheses for single-parameter parameter lists, etc.
Functions with multiple parameter lists are called in a similar way to a curried functions from a syntactic perspective, but by default, the intermediate functions aren't created. In fully curried style, each function takes only at most one argument and returns one result (which might happen to be another function, which expects on argument, and so forth). Technically, currying the function would be:
def product2(f: Int => Int): Int => Int => Int = {
a: Int => {
b: Int => {
if(a > b ) 1
else f(a) * product2(f)(a+1)(b)
}
}
}
For completeness, you can treat a function with multiple parameter lists as a curried function by using an underscore after a complete parameter list. In your original example, you'd do product1(f)_, which would return a function of type (Int, Int) => Int.
In researching this question, I came upon another SO question worth checking out to understand this aspect of the language better.