Declaring functions two ways. What is the distinction?
scala
Solution
The first is a no-argument method `f1` that returns a `Function1[Int, Int]`.
scala> def f1: (Int => Int) = (x: Int) => x * x
f1: (Int) => Int
The second is a one argument method `f2` that takes an an `Int` and returns an `Int`.
scala> def f2(x: Int): Int = x * x
f2: (x: Int)Int
You can invoke f1 and f2 with the same syntax, although when you call `f1(2)` it is expanded to `f1.apply(2)`.
scala> f1
res0: (Int) => Int = <function1>
scala> f1(2)
res1: Int = 4
scala> f1.apply(2)
res2: Int = 2
scala> f2(2)
res3: Int = 4
Finally, you can 'lift' the method `f2` to a function as follows.
scala> f2
<console>:6: error: missing arguments for method f2 in object $iw;
follow this method with `_' if you want to treat it as a partially applied funct
ion
f2
^
scala> f2 _
res7: (Int) => Int = <function1>
scala> (f2 _).apply(2)
res8: Int = 4
Exercise: What is the type of `f1 _`?
Problem
Are these two function declarations effectively different? If not, why do they have different toString values? ``` scala> def f: (Int) => Int = x=> x*x f: (Int) => Int scala> def f(x: Int) = x*x f: (Int)Int ```