This question is about _ as used in type constructor and not when used in defining existential types.
So the question is what is the difference when _
is us
To quote the specification:
The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter
t
) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of t. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a_
, which is nowhere visible.Example
Here are some well-formed type parameter clauses:
[S, T] [@specialized T, U] [Ex <: Throwable] [A <: Comparable[B], B <: A] [A, B >: A, C >: A <: B] [M[X], N[X]] [M[_], N[_]] // equivalent to previous clause [M[X <: Bound[X]], Bound[_]] [M[+X] <: Iterable[X]]
So if you have no bounds, as in Functor [F[T]]
, there's no difference at all from Functor [F[_]]
.