scalatypestype-constructor

Difference between F[_] and F[T] In Scala when used in type constructors


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 used as type parameter instead of a variable like T. For example difference between F[_] and F[T].

The only difference I can think of is that with F[_] the parameter itself can have as many holes as possible...that is F[_] can become F[Int] or F[Future[Option[Int]]] etc...while when you have F[T] the T can only be a proper type...that is F[String] or F[Int] etc.

Is this a correct assumption? and is that the main difference between F[_] and F[T]? or there are more?

What about the case where the two are used as type parameters? For example, what is the difference between trait Functor [F[_]] and trait Functor [F[T]]?

Is there any semantic difference if the functor trait is defined as trait Functor [F[_]] instead of trait Functor [F[T]]?


Solution

  • 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[_]].