Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a partial function applied to 2 functions that do the same thing defined in 2 different ways return a different result?

Tags:

scala

I can define the following two functions:

def add(a: Int, b: Int, c: Int) = a + b + c

this results in

add: (a: Int, b: Int, c: Int)Int

and

val add2 = (a: Int, b: Int, c: Int) => a + b + c

this results in

add2: (Int, Int, Int) => Int = <function3>

Both of these are functions that do the exact same thing but defined in a different way, what I do not understand is if I go ahead and define a partially applied function as follows:

def a = add _

This results in

a: (Int, Int, Int) => Int = <function3> 

as expected, a function that takes 3 parameters and returns an Int, but if I do

def a2 = add2 _

This results in

a2: () => (Int, Int, Int) => Int = <function0>

which seems to be a function that takes no parameters and returns a function that takes 3 Int parameters and returns an Int. Why does this happen? Can someone please explain what is going on?

thanks

like image 532
kgrad Avatar asked Mar 03 '12 04:03

kgrad


People also ask

What is a partial function explain with a suitable example?

For example, let's say you have inputs A, B, and C. They might map to X, Y, and Z, as shown in the blue circle on the left: The blue circle is a function; The orange circle is missing a link from one output (B), and so is a partial function. But sometimes, not every input matches to an output.

Is a partial function a function?

A partial function is a function that is not defined for all possible arguments of the specified type.

What is partial function give its expression?

In mathematics, a partial function f from a set X to a set Y is a function from a subset S of X (possibly X itself) to Y. The subset S, that is, the domain of f viewed as a function, is called the domain of definition of f. If S equals X, that is, if f is defined on every element in X, then f is said to be total.

What is partially applied function in Scala?

The Partially applied functions are the functions which are not applied on all the arguments defined by the stated function i.e, while invoking a function, we can supply some of the arguments and the left arguments are supplied when required.


2 Answers

This is a strange side-effect of Scala not actually having (user-accessible) fields, but instead having accessors (getters) for everything. Observe:

scala> val i = 1
i: Int = 1

scala> i _
res0: () => Int = <function0>

The reason is that i is actually an accessor (def i: Int) to an underlying (hidden, inaccessible) field. Since it's just a method, _ will convert it into a function. The accessor doesn't take any arguments, which is why you have a function that takes no parameters.

like image 185
Rex Kerr Avatar answered Nov 05 '22 14:11

Rex Kerr


Scala has both functions and methods, they are not quite the same thing.

def add(a: Int, b: Int, c: Int) = a + b + c

Which defined a method (not a function!!).

val add2 = (a: Int, b: Int, c: Int) => a + b + c

Which assigned add2 a function value(not a method!!).

A method can’t be the final value, while a function can:

scala> add
<console>:9: error: missing arguments for method add;
follow this method with `_' if you want to treat it as a partially applied function
              add
              ^

scala> add2
res1: (Int, Int, Int) => Int = <function3>

scala> val a = add
<console>:8: error: missing arguments for method add;
follow this method with `_' if you want to treat it as a partially applied function
       val a = add
               ^

scala> val a2 = add2
a2: (Int, Int, Int) => Int = <function3>

Writing an underscore after the method name can explicitly convert a method into a function:

scala> add _
res2: (Int, Int, Int) => Int = <function3>

But if you writing an underscore after a value, it will convert to a function which take no argument with return type of its type:

scala> val s = ""
s: String = ""

scala> val i = 1
i: Int = 1

scala> s _
res3: () => String = <function0>

scala> i _
res4: () => Int = <function0>

So if the value itself is a function, writing an underscore after it will get a new function which take no argument with return type of function:

scala> add2 _
res5: () => (Int, Int, Int) => Int = <function0>
like image 26
Eastsun Avatar answered Nov 05 '22 15:11

Eastsun