Reputation: 28433
For instance, List[T] forSome { type T }
is equivalent to List[_]
, but is this true for every possible usage of forSome
or are there cases where forSome
cannot be replaced by an equivalent of the second syntax?
Upvotes: 12
Views: 279
Reputation: 134270
No, not all usages can be thus converted. Something like this (thanks to retronym, below, who should be getting the upvotes on this one)
def foo(xs: Map[T, T] forSome { type T})
The point here is that I can use the existential in more than one place but it is the same existential. Obviously, if you used wildcards, you would be referring to different existentials
Upvotes: 15
Reputation: 55028
_
in this context is the "Placeholder Syntax for Existential Types", described in 3.2.10 of the language specification.
The name sounds a lot like another use of _
, "Placeholder Syntax for Anonymous Functions". This shorthand can't be used for all functions. For example:
(a: A) => f(g(a))
f(g(_: A)) // WRONG, this means f((a: A) => g(a))
We can construct a similar example for existentials, which can't be represented _
:
F[G[A]] forSome { type A }
F[G[_]] // WRONG, this means F[G[A] forSome { type A }]
Side note: existentials are not the type level analog of value level functions. That would be:
({type l[A] = F[G[A]])#l
In fact it's a pity that Scala uses the underscore for existentials, rather than type level functions.
UPDATE
Let me frame @oxbow_lakes' answer in the same way:
(a: A) => h(a, a)
h(_, _) // WRONG, this means (a, b) => f(a, b)
H[A, A] forSome { type A }
H[_, _] // WRONG, this means H[A, B] forSome { type A; type B }
Upvotes: 14