Scala: What is wrong with my method? - scala

I have a method fun. It takes a function literal as a parameter and return Int.
def fun(arg: (Int) => Int): Int = {
val ret = 5 * arg + 10
ret
}
It represent a function f(x) = 5x+10, which could take a parameter as another function (i.g. g(x) = x+1), so f(g(2)) = 5(2+1)+10 = 25
But my Scala code doesn't compile. Why?

Scala is a functional programming language, it has a very nice feature where we can pass functions as arguments, to store them in variables, and to return them from other functions.
object FunctionCalc{
def f(Input: Int => Int) : Int ={
val temp = 10
(Input(5) + temp ) // It takes functions as input which take input as Int and return Int.
}
def f(Input:Int) :Int ={
Input + 4 //overloaded function
}
def g(arg : Int) :Int= {
arg+1 //adding 1
}
def h(arg:Int) : Int ={
arg+3 //adding 3
}
def main(args: Array[String]) {
println( f(g(2)))
println(f(h(4)))
println(f(6))
}
}
Consider the above example we are passing functions g and h as inputs to f().

Because you are using function "arg:Int=>Int" as and argument in your code.
"arg" is a function you can use it like this.
def g(x:Int) = x+1
def f(arg:Int=>Int)(y:Int) = 5* arg(y) + 10
scala> f(g)(2)
res23: Int = 25

Related

convert a method call with parameters to a Function that takes no parameters

Creating a function from method call that takes no parameters requires below syntax :-
val d = display _
How to do the same thing for method call with parameters.
Please find below sample code.
package paf
/**
* Created by mogli on 8/27/17.
*/
object PafSample {
def display(): Unit ={
println("display is a no argument method")
}
def evenOdd(input : Int) : Unit = if(input % 2 == 0) println(s"$input is even") else println(s"$input is odd")
def main(args: Array[String]): Unit = {
//This is working
val d = display _
executeFunction(d)
//TODO : convert to a function call that takes no arguments,
// so that, it can be passed to executeFunction as parameter
//val e = evenOdd(3) _
//executeFunction(e)
}
def executeFunction[B](f : () => B) : B = {
println("executing function")
f()
}
}
That's not going to work. executeFunction is a method taking a function which takes on parameters and returns a B. evenOdd takes a single parameter of type Int and yields Unit, meaning Int => Unit.
You'll need to accept a parameter:
def executeSingleArgFunction[A, B](a: A)(f: A => B): B = {
f(a)
}
And then:
executeSingleArgFunction(3)(evenOdd)

High order functions in Scala

IM trying to understand the below high order functions in Scala but need some clarifications on the parameters of the functions.
Questions:-
What does the Int => String in the apply function mean?
v: Int indicates that the parameter v is of type Int.
What does the [A](x: A) mean in layout function?
object Demo {
def main(args: Array[String]) {
println( apply( layout, 10) )
}
def apply(f: Int => String, v: Int) = f(v)
def layout[A](x: A) = "[" + x.toString() + "]"
}
f: Int => String means that f is a function with one argument of type Int and with a return type String
def layout[A](x: A) means that parameter x is of type A, which can be of any type. Here are a couple of examples on how to invoke layout:
layout[String]("abc") //returns "[abc]"
layout[Int](123) //returns "[123]"
When main runs it invokes apply with the layout function and the argument 10. This will output "[10]"
The syntax of Int => String means passing a function that accepts Int and returns String.
Here is a useful example for passing function:
case class Person(name: String, lastName: String)
val person = Person("Johnny", "Cage")
def updateName(name: String) = {
updatePerson(_.copy(name = name))
}
def updateLastName(lastName: String) {
updatePerson(_.copy(lastName = lastName))
}
private def updatePerson(transformer: Person => Person): Unit = {
transformer(person)
}
Note how each update function passes the copy constructor.

why does scala use = operator while defining function

I am new to scala. I have worked on java. defining of function in scala by using = operator does not make sense for me.
def abc(a:Int,b:Int):Int =
a+b
can anybody explain? in the above code, why i had to use = operator.
I believe there are many reasons. Just some of them:
1) uniform access:
val abc: Int = 5 //value
def abc: Int = 5 //factory
Note that such def abc can be implemented with val abc inside successor:
trait Interface {
def abc: Int //factory (reader)
}
object Implementation extends Interface {
val abc: Int = 5 //singleton
}
Some advanced examples: Why it's impossible to override `var` with `def` in Scala?
2) functions are just named lambda's:
val abc = (a: Int, b: Int) => a + b //lambda assigned to abc value
def abc (a:Int, b:Int): Int = a + b //abc method, that could be converted to lambda/function with eta-expansion: "abc _"
The syntactic difference between first and second one is just position of braces, so they are quite similar.
3) that function actually returns value, you might think of the a + b block independently from function definition, so then:
def abc ...: Int = {
val z = a + b
z
}
is almost like
val abc: Int = {
val z = a + b
z
}
But a and b are unknown, so we need to describe them too:
def abc(a: Int, b: Int): Int = {
val z = a + b
z
}
Otherwise, if your method doesn't return anything, you can omit = sign:
def abc(a: Int, b: Int) {
println(a + b)
}
Which is equivalent to:
def abc(a: Int, b: Int): Unit = {
println(a + b)
}
Where Unit (inhabited type with only one possible value, so it contains no information) roughly means that no value was returned.
See also official doc and language spec
This approach enhances the functional aspect of programming, where functions are no different than other data types.
e.g. In Scala
val number = 10
val function = (a:Int, b:Int) => a + b
Here, both the values number and function are immutable variables. Only difference is their types. number is of type Int, while function is of type (Int, Int) => Int
This enables functions to be treated just like Data and be passed around like other variables. This enhances into concepts like Higher Order Functions which can accept and return function values as opposed to literal values. As #dk14 mentioned, it's about uniform access.
There is one reason I know why scala uses = in method declaration is:
To return any value from method definition ,= has to be used or it cant return any value even if there is a return statement in method.
For Eg: look at below two code snippets:
def method1()
{
val a=1
return a
}
def method2()=
{
val a=1
return a
}
method1 return type is always unit even if it returns some values
whereas method2 returns value a .

Scala: function as a parameter to map()

How to use the map method in the Iterable trait in the example below?
As I understand this method will return a function which I have to call to execute internal logic.
trait Container[E] {
def += (e: E): Unit
}
trait Iterable[E, C[X] <: Container[X]]
{
def iterator(): Iterator[E]
def build[F](): C[F]
def map[F](f : (E) => F) : C[F] = {
val res = build[F]()
val iter = iterator()
while (iter.hasNext) res += f(iter.next())
res
}
}
class Buffer[T] extends Container[T]
{
val list = scala.collection.mutable.ListBuffer.empty[T]
def Children = list
def += (e: T): Unit = list += e
}
class Range(val low: Int, val high: Int) extends Iterable[Int, Buffer] {
def iterator() = new Iterator[Int]
{
private var i = low
def hasNext = i <= high
def next() = { i += 1; i - 1 }
}
def build[F]() = new Buffer[F]
}
val range = new Range(1, 3)
var list = range.map[String](_)
The method in question has the following signature:
trait Iterable[E, C[X] <: Container[X]] {
def map[F](f : (E) => F) : C[F]
// ...
}
First, let's look at the type of f argument. The signature (E) => F says that f is a function which takes a single argument of type E and returns a value of type F. Any function (or method) with this signature can be passed to map() as argument. See also Scala documentation.
Another important thing to understand is that the map function is generic with type parameter F. Value for this type parameter can either be specified manually or inferred by the compiler from the argument passed to map:
new Range(1,2).map[String](_.toString) // F is String
// new Range(1,2).map[Int](_.toString) // F is Int, compilation will fail
val mapFunction: Int => String = _.toString
new Range(1,2).map(mapFunction) // mapFunction is a function from Int to String,
// the compiler infers F is String
Basically, e.g. with Range, you can pass to the map() function any function which takes a single Int parameter (because Range binds E to Int) and returns anything (except for Unit). A few more examples:
val r = Range(1,2)
val v1: Buffer[String] = r.map(_.toString)
val v2: Buffer[Int] = r.map(i => i + 1)
val v3: Buffer[Double] = r.map(Int.int2double)
val i: Int = 1
val v4: Buffer[Int] = r.map(i.max)
As you can see, map() returns type Buffer[F] because that's what Range binds to the C[X] type parameter.
As #vitalii noted, the question is not related to higher-kinded types. For more information about those, check out other questions or blogs.
new Range(2,5).map(_.toString)

Scala partial application unclear

I don't have very clear the partial application of functions in Scala...
I will do an example:
def myOperation(x: Int)(y: Int): Int = {
val complexVal = complexCalc(x)
println("complexVal calculated")
complexVal + y
}
def complexCalc(x: Int): Int = x * 2
val partial = myOperation(5)_
println("calculate")
println("result(3): " + partial(3))
println("result(1): " + partial(1))
The output of this will be:
calculate
complexVal calculated
result(3): 13
complexVal calculated
result(1): 11
So the complexVal was calculated 2 times, what if I want to calculate it just once?
For who has javascript knowledge something like:
function myOperation(x) {
var complexVal = complexCalc(x)
return function(y){
complexVal + y
}
}
EDIT:
So what's the difference between what I've written previously and this:
def myOperation2(x: Int, y: Int): Int = {
val complexVal = complexCalculation(x)
println("complexVal calculated")
complexVal + y
}
val partial = myOperation(5)_
val partial2 = myOperation2(5, _: Int)
You can explicitly return a function from myOperation:
def myOperation(x: Int): Int => Int = {
val complexVal = complexCalc(x)
println("complexVal calculated")
(y: Int) => complexVal + y
}
Partial application just creates a new function by filling in some of the arguments of an existing function, but does not actually execute any part of that function.
For what you're trying to do, you want to return a function from a function. In this case, what you're actually doing is currying (true currying).
Try this:
def myOperation(x : Int) : (Int => Int => Int) = {
val complexVal = complexCalc(x)
(y : Int) => complexVal + y
}
Partial application binds a value to a function argument to give you a function with decreased arity (i.e. fewer arguments). This does not provide any form of memoisation of your expensive computation.
Lee's answer is perfectly good way of solving that problem.