Reputation: 2080
Given Scala 2.12.6:
val list = List(1)
val x = 2
This works:
list.map ( y => x + y )
returning List[Int] = List(3)
and this works:
list.map ( (y: Int) => x + y )
returning the same value.
Same for this:
list.map { (y: Int) => x + y }
And same for this:
list.map { y: Int => x + y }
Yet this fails:
list.map ( y: Int => x + y )
producing the error:
error: not found: type +
list.map ( y: Int => x + y )
^
Why is Scala thinking the +
is meant to indicate a type, and where is this difference between using parenthesis and curly braces documented and explained?
Upvotes: 2
Views: 385
Reputation: 44908
The Section 6.23 about anonymous functions says:
In the case of a single untyped formal parameter, (x) => e can be abbreviated to x => e. If an anonymous function (x: T) => e with a single typed parameter appears as the result expression of a block, it can be abbreviated to x: T => e.
Thus, in a block { ... }
, the function literal (y: Int) => x + y
can be abbreviated to just y: Int => x + y
.
Without the block, the entire Int => x + y
-part is treated as type ascription, so the error message actually makes sense. For example, here is a context in which the offending expression becomes valid:
type y = Unit
type x = Unit
type +[A, B] = Int
val y = (i: Int) => 42 + i
val list = List(1)
println(
list.map ( y: Int => x + y )
) // happily prints `List(43)`.
This is because there are two y
s in two separate scopes (one value, one type alias), so that (y: Int => x + y)
becomes (y: Int => +[x, y])
, and then (y: Int => Int)
, which is just a type ascription enforcing that value y
is indeed of function type Int => Int
(which it is, so everything compiles and runs). Here is another similar example.
My suggestion: stick to the slightly more verbose (foo: Foo) => { ... }
notation, it will cause fewer surprises for everyone who tries to read and to modify the code. Otherwise there is some risk that
=>
of the anonymous lambda collides with function type =>
+
collides with binary infix type constructor +[_,_]
x
, y
collide with undefined types x
, y
.The fact that same syntax can denote both types and expressions can be somewhat of a double-edged sword.
Upvotes: 4