I have a very simple piece of code that I am not able to get grasp of. I am reading function literals, and methods. I am doing this in repl.
scala> val v = (a:Int, b:Int, c:Int) => {a+b+c}
v: (Int, Int, Int) => Int = $$Lambda$1368/1731643198@4ae730ca
scala> val v1 = v(1,2,_:Int)
v1: Int => Int = $$Lambda$1369/903167315@93d6f4
scala> v1 (10)
res29: Int = 13
scala>
scala> val v2 = v _
v2: () => (Int, Int, Int) => Int = $$Lambda$1370/5485285@7dd5d17a
scala> val v3 = v2()
v3: (Int, Int, Int) => Int = $$Lambda$1368/1731643198@4ae730ca
scala> val v4 = v3(1,2,3)
v4: Int = 6
scala> def sumMe(a:Int, b:Int, c:Int) = { a+b+c}
sumMe: (a: Int, b: Int, c: Int)Int
scala> val v7 = sumMe _
v7: (Int, Int, Int) => Int = $$Lambda$1371/906350712@6c86938f
scala> v7(1,2,3)
res30: Int = 6
I need some help in understanding on what happens above. I will start from the bottom of the code. When I create the method sumMe and assign it to "v7" with "_" on the right, I know I am not executing the method. The output of val v7= sumMe_
is quite clear to me as it simply tells me that v7 will take 3 params, and return an int. It feels OK so far.
Now when I go to my `val v1 = v(1,2,_:Int), I can still correlate that it will create a function object and assign to v1 and in fact I am using Scala s Function1's apply method is what I view it as.
I am hoping I understand it right so far. If my understanding above is right, what causes the most confusion is val v2 = v _
. And based on the output of what I see I have to call this thing differently. Basically I am not able to understand why v2 is different from v7. v2 takes no arguments and gives me a function which I can call. If that is always the case with function literals of the kind that I have defined as val v = ...
, then when I do val v1 = v(1,2,:_Int)
why don't I get this from scala v1:()=>Int=>Int
which is similar to v2's case
.
And lastly, why won't v7=sumMe _
not give me the same output as val v2 = v_
In Scala, we differentiate methods from functions . When you define sumMe
, you're defining a method, while your other declarations are functions. Methods, in Scala, are non value types , meaning the method itself has no value. When you try to assign it to a value, there is an implicit conversion called eta expansion that is done to convert it to the corresponding function type. From the specification:
Method types do not exist as types of values. If a method name is used as a value, its type is implicitly converted to a corresponding function type.
Now that we're equipped with the knowledge of methods and functions, lets analyze what happens.
When I create the method
sumMe
and assign it to "v7" with "_" on the right, I know I am not executing the method
That's right. When you do sumMe _
, you're using eta-expansion to convert the method to a function.
Now when I go to my
val v1 = v(1, 2, _: Int)
, I can still correlate that it will create a function object and assign to v1
Again, you're right. v1
is now a partially applied function of type Function1[Int, Int]
.
Basically I am not able to understand why v2 is different from v7.
What is v2
? It is a function object which was created by partially applying an existing function object. Since this function of type Function3[Int, Int, Int, Int]
is already fixed in it's parameter list, partially applying it only nests it in another function object, now of type Function0
, making it a Function0[Function3[Int, Int, Int, Int]]
.
In Scala, functions are value that means you can assign any function in a variable. Whenever you apply placeholder("_") in front of def it will convert def into function with same input and output types. If you apply placeholder in front of value it will convert into function that take unit as input and return value as output**[() => T]**. for example:
scala> val a = 2
a: Int = 2
scala> val fun1 = a _
fun1: () => Int = <function0>
scala> def sum(a:Int, b:Int) = a+ b
sum: (a: Int, b: Int)Int
scala> val fun2 = sum _
fun2: (Int, Int) => Int = <function2>
whenever you are trying to pass partial input parameters in a "def" it will return partial applied function. For example:
scala> val fun3 = sum(1,_:Int)
fun3: Int => Int = <function1>
fun3 is called partial applied function.
There are something need to clear for function
and method
,
function : we use val
and var
to define the function
, it's often is an Anonymous Function
, In Scala , there are Function0
, Function1
, Function2
... for these Anonymous Function
, and the function type like: (T0, T1...TN) => U
.
so function
v
actually is aFunction3
with 3 parameters.
method : it's used to def
to declare with method
body with the parameters and return type
.
For val v2 = v _
actually equals to val v2 = () => v
, in there wildcard _
will expand to () => v
, and v2
means it's a function to create another function( v
) without parameter.So val v3 = v2()
means invoke v2()
to create v
function, so essentially v3
equal to v
.
For val v7 = sumMe _
this means convert method sumMe
to a function, in there wildcard _
will expand to (a: Int, b: Int, c: Int) => sumMe(a, b, c)
, so sumMe _
will create a new function that's essentially equal to v
, if you use v7 _
it also will create the same function
like val v2 = v _
.
Reference :
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.