Given
scala> def method(x: Int) = x
method: (x: Int)Int
scala> val func = (x: Int) => x
func: Int => Int = <function1>
Consider the following code:
scala> method _
res0: Int => Int = <function1>
scala> func(_)
res1: Int => Int = <function1>
scala> func _
res2: () => Int => Int = <function0>
I can understand that res0
is eta expansion and res1
is equivalent to lambda function (x) => func(x)
. But I cannot figure out the output of res2
. Could anyone please explain that for me?
An underscore, _, also called an underline, low line or low dash, is a line drawn under a segment of text. In proofreading, underscoring is a convention that says "set this text in italic type", traditionally used on manuscript or typescript as an instruction to the printer.
The _. property() function is used to return a function that will return the specified property of any passed-in object.
The _. flip() method returns a function that works identically to given function but accepts the arguments in reverse order.
Underscore. js is a utility-belt library for JavaScript that provides support for the usual functional suspects (each, map, reduce, filter...) without extending any core JavaScript objects. For Docs, License, Tests, and pre-packed downloads, see: https://underscorejs.org.
This is actually a bit tricky. First, let's see what happens outside REPL:
It doesn't work when func
is a local variable:
object Main extends App {
def foo() = {
val f = (_: Int) + 1
f _
}
println(foo())
}
[error] /tmp/rendereraEZGWf9f1Q/src/main/scala/test.scala:8: _ must follow method; cannot follow Int => Int
[error] f _
[error] ^
But if you put it outside def foo
, it compiles:
object Main extends App {
val f = (_: Int) + 1
val f1 = f _
println(f1)
}
because f
is both a field of Main
and a method without arguments which returns the value of this field.
The final piece is that REPL wraps each line into an object (because Scala doesn't allow code to appear outside a trait/class/object), so
scala> val func = (x: Int) => x
func: Int => Int = <function1>
is really something like
object Line1 {
val func = (x: Int) => x
}
import Line1._
// print result
So func
on the next line refers to Line1.func
which is a method and so can be eta-expanded.
You've used the eta Expansion to turn res2
into a function that takes 0 parameters and returns a function that takes a single parameter.
res2: () => Int => Int = <function0>
So you can now do this:
val zero = func _
val f: Int => Int = zero()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With