The meaning of underscores on the left of arrow =>
(_: Int, _: Int) => ...
are different from the meaning of underscores around the infix operator /
(_: Int) / (_: Int)
The former mean something like
"We are defining a function that takes two arguments, however
we will not use these arguments in the body of the function"
whilst the latter is a shorthand for defining a function of two arguments
(x: Int, y: Int) => x / y
For example,
(_: Int, _: Int) => (_: Int) / (_: Int)
desugars to something like
(a: Int, b: Int) => ((x: Int, y: Int) => x / y)
where we see arguments a
and b
are not used in the body which happens to be yet another function ((x: Int, y: Int) => x / y)
.
Daniel documents the two meanings as
_ + _ // Anonymous function placeholder parameter
_ => 5 // Discarded parameter
As a side-note, consider a somewhat analogous situation at the typelevel involving type constructors and their bounds where the meaning of underscore depends on the context
CC[_] <: Iterable[_]
Personally, my mind tricks me to think it is equivalent to
CC[x] <: Iterable[x]
however that is not the case, and the meaning of the underscore on the left of <:
is different from the meaning on the right
CC[x] <: Iterable[y] forSome {type y}
Note how x
does not appear in Iterable[y] forSome {type y}
. Adrian documents this under Common Pitfalls:
...perhaps surprisingly, CC[_] <: Traversable[_]
is not equivalent to
CC[X] <: Traversable[X]
. The former expands to CC[X] <: Traversable[T] forSome {type T}
, where T
is existentially bound and thus unrelated to
X
.
and in a comment to type bounds on type constructor
comparing the level of types and values, it is quite unfortunate that
the type-level underscore behaves differently from the value-level
underscore. At the value level, _ + _
indeed stands for (x, y) => x + y
, a function. As hinted at in my other comment, the type-level
underscore is context-sensitive, and it never introduces a type-level
function. It's either an anonymous type parameter definition or an
anonymous existential. Neither of these have value-level equivalents.
Hence we should be careful to interpret the meaning of the underscore within its context.