Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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]]?

like image 865
dade Avatar asked Apr 10 '18 20:04

dade


People also ask

What is f [_] in Scala?

The F[_] simply means that F is a type parameter , which is itself a type constructor or a type with a type parameter . As we stated earlier, such a type can be a List , Option , or even a Scala Future .

What is type constructor in Scala?

You can use certain types (like Int or String ) using literals ( 1 or 2 for Int or "James" for String ). Type constructors are types that need other types to be built. List or Option won't be a fully qualified type unless you pass another type to them (i.e. List[Int] or Option[String] – mfirry.

How does Scala determine types when they are not specified?

Non-value types capture properties of identifiers that are not values. For example, a type constructor does not directly specify a type of values. However, when a type constructor is applied to the correct type arguments, it yields a first-order type, which may be a value type.

What are type parameters in Scala?

Methods in Scala can be parameterized by type as well as value. The syntax is similar to that of generic classes. Type parameters are enclosed in square brackets, while value parameters are enclosed in parentheses. The method listOfDuplicates takes a type parameter A and value parameters x and length .


1 Answers

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

like image 98
Alexey Romanov Avatar answered Sep 19 '22 16:09

Alexey Romanov