How to make scala shell to show an anonymous function? - scala

I am learning scala and a typical example is the definition of an anonymous function:
scala> (x: Int) => x + 7
res11: Int => Int = <function1>
How do I make the shell to show me the body of <function1>?
Which would be x + 7 in the above case.
This becomes interesting if a function is partially applied:
scala> def adder(m: Int, n: Int) : Int = m + n
adder: (m: Int, n: Int)Int
scala> val add2 = adder(2, _:Int)
add2: Int => Int = <function1>

Related

Why scala can't pass a function name directly to a val?

I have this scala code:
object C extends App{
def sum(a:Int,b:Int,c:Int)=a+b+c
//val d=sum
val d=sum _
println(d(1,2,3))
}
I have to write sum _,not sum
but In f#,I can write this:
let sum a b c=a+b+c
let d=sum
[<EntryPoint>]
let main argv =
printfn "%A" (d 1 2 3)
0 // return an integer exit code
why in scala I can't just write
val d=sum
Scala has
methods (by default def is a method) and
functions
And they are not same.
Taking java methods as example, you can not assign methods to a variable without evaluating the method. But you can do that with function and to achieve that in scala define sum as function.
scala> def sum: (Int, Int, Int) => Int = (a, b, c) => a + b + c
sum: (Int, Int, Int) => Int
scala> val sumVal = sum
sumVal: (Int, Int, Int) => Int = $$Lambda$912/0x0000000801667840#716f94c1
scala> sumVal(1, 2, 3)
res1: Int = 6
Longer version of defining a function is,
scala> def sum = new Function3[Int, Int, Int, Int] {
| def apply(a: Int, b: Int, c: Int): Int = a +b + c
| }
sum: (Int, Int, Int) => Int
scala> val sumVal = sum
sumVal: (Int, Int, Int) => Int = <function3>
scala> sumVal(1, 2, 3)
res2: Int = 6

Calling a function with arguments in a method scala

Suppose I have functions that takes 2 Ints and returns 1 Int:
val sub : (Int, Int) => Int = (x,y) => x - y
val mul : (Int, Int) => Int = (x,y) => x * y
How will I create a method that accepts the above type. I tried:
def test(f:(Int,Int) => Int) : Unit = {
val a = f
println(a)
}
Which does not seem to work.
I guess by "Does not seem to work.", you mean you're trying to call the function and expected an output in the println.
The function works as designed. It's just not the way you probably hoped it will work...
So this for instance will not work:
scala> test(sub(5, 3))
<console>:14: error: type mismatch;
found : Int
required: (Int, Int) => Int
test(sub(5, 3))
But you can modify test() slightly:
scala> def test(f:(Int,Int) => Int, x: Int, y: Int) : Unit = {
| val a = f(x, y)
| println(a)
| }
test: (f: (Int, Int) => Int, x: Int, y: Int)Unit
And call it with the params:
scala> test(sub, 5, 3)
2
scala> test(mul, 5, 3)
15

High-Order Function [duplicate]

This question already has answers here:
Currying syntax in scala
(2 answers)
Closed 5 years ago.
In the course of funcional programming with Scala, I saw two form of declaration of a def. But I don't know the diferences between them, and the name given for this. How I can get more information about this?
Declaration 1
def sum(f: Int => Int)(a: Int, b: Int): Int = ???
Declaration 2
def sum(f: Int => Int, a: Int, b: Int): Int = ???
First one is called the curried syntax.
You can apply the function partially, then results in returning of a new function.
scala> def sum(f: Int => Int)(a: Int, b: Int): Int = f(a) + f(b)
sum: (f: Int => Int)(a: Int, b: Int)Int
scala> sum({x: Int => x + 1}) _
res10: (Int, Int) => Int = $$Lambda$1115/108209958#474821de
Second one is uncurried syntax but still we can apply the function partially even in this case.
scala> def sum(f: Int => Int, a: Int, b: Int): Int = f(a) + f(b)
sum: (f: Int => Int, a: Int, b: Int)Int
scala> sum({x: Int => x + 1}, _: Int, _: Int)
res11: (Int, Int) => Int = $$Lambda$1116/1038002783#1a500561
Again new function returned when applied partially.
There is no difference between above two declaration, Its just the syntactic sugar.

why currying does not work with a function literal?

What is the logical reason that the first form works and not the second?
scala> val d = (a: Int, b: Int) => a + b
d: (Int, Int) => Int = <function2>
scala> val d = (a: Int)(b: Int) => a + b
<console>:1: error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
val d=(a:Int)(b:Int)=>a+b
Because multiple parameter lists aren't allowed on function declarations. If you want to curry a function, you do:
scala> val d: Int => Int => Int = a => b => a + b
d: Int => (Int => Int) = $$Lambda$1106/512934838#6ef4cbe1
scala> val f = d(3)
f: Int => Int = $$Lambda$1109/1933965693#7e2c6702
scala> f(4)
res6: Int = 7
You can also create a single parameter list and partially apply it:
scala> val d = (a: Int, b: Int) => a + b
d: (Int, Int) => Int = $$Lambda$1064/586164630#7c8874ef
scala> d(4, _: Int)
res2: Int => Int = $$Lambda$1079/2135563436#4a1a412e
We partially applied d with 4, and we got back a function, Int => Int, which means when we supply the next argument, we'll get the result:
scala> res2(3)
res3: Int = 7
We can also create a named method, and use eta-expansion to create a curried function out of it:
scala> def add(i: Int)(j: Int): Int = i + j
add: (i: Int)(j: Int)Int
scala> val curriedAdd = add _
curriedAdd: Int => (Int => Int) = $$Lambda$1115/287609100#f849027
scala> val onlyOneArgumentLeft = curriedAdd(1)
onlyOneArgumentLeft: Int => Int = $$Lambda$1116/1700143613#77e9dca8
scala> onlyOneArgumentLeft(2)
res8: Int = 3
Function currying is possible.
val curryFunc = (a: Int) => (b: Int) => a + b
curryFunc now has the type Int => (Int => Int)

Combining partial functions

I came from Java and would like to combine two partial functions like this:
def sum(a: Int, b: Int, c: Int) : Int = a + b + c
I want write something like this:
val l = List(1, 2, 3)
l.foreach(println _ sum (1, _ : Int, 3) ) // It's supposed to apply
// the partial sum(1, _: Int, 3)
// and println computed value.
But it refuses to compile. Is there a way to fix it concisely?
There are few problems with what you were trying to do. First of all, println is an overloaded method, so when you are trying to eta-expand it to a function like this println _, Scala is taking the shortest form, which is the one with 0 arguments:
scala> println _
res0: () => Unit = $$Lambda$1048/48841776#58ec44ec
So you need to be more specific:
scala> println(_: Int)
res1: Int => Unit = $$Lambda$1064/1621799037#1e8bddc4
Now that we have correct function there is one more thing to do: to add compose and proper parentheses (additional parentheses wrap anonymous functions):
scala> l.foreach((println(_: Int)) compose (sum (1, _: Int, 3)))
5
6
7
or in the other direction:
scala> l.foreach((sum (1, _: Int, 3)) andThen (println(_: Int)))
5
6
7
Assuming I reading what you want correctly (and even the code it's a huge assumption), here a snippet that might achieve it:
scala> def sum(a: Int, b: Int, c: Int) : Int = a + b + c
sum: (a: Int, b: Int, c: Int)Int
scala> val sum13 = sum(1, _ : Int, 3)
sum13: Int => Int = <function1>
scala> val printInt = println( _ : Int )
printInt: Int => Unit = <function1>
scala> List(1,2,4) foreach { printInt compose sum13 }
5
6
8
Notice the compose. Another way would be explicitly compose x => printInt(sum13(x)).