Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Underscore after function?

Tags:

scala

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?

like image 615
Lifu Huang Avatar asked Sep 19 '16 12:09

Lifu Huang


People also ask

What is the function of Underscore?

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.

What does the _ property function return?

The _. property() function is used to return a function that will return the specified property of any passed-in object.

What is the use of underscore flip function?

The _. flip() method returns a function that works identically to given function but accepts the arguments in reverse order.

What is underscore NPM?

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.


2 Answers

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.

like image 114
Alexey Romanov Avatar answered Nov 02 '22 09:11

Alexey Romanov


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()
like image 27
Luka Jacobowitz Avatar answered Nov 02 '22 09:11

Luka Jacobowitz