Search code examples
scalatypestype-parameter

Book: Scala in Depth, def foo[M[_]](f : M[Int]) = f, is _ really an existential type here?


On page 136. page of the book "Scala in Depth" it is written:

enter image description here

But the following experiment suggests that here _ is just the same as any arbitrary type parameter T, so it is perhaps not an existential type.

scala> def foo[M[_]](f : M[Int]) = f
foo: [M[_]](f: M[Int])M[Int]


scala> def foo[M[T]](f : M[Int]) = f
foo: [M[T]](f: M[Int])M[Int]

Also note the section 4.4 of the Scala Language Specification below , this also suggests that _ is the same as T here.

Can someone explain what is going on here ?

enter image description here


Solution

  • M[_] in that context (i.e. as a type parameter declaration) is a higher kinded type (sometimes called a "type constructor"); as you say it's the same as M[X], with the _ just meaning we aren't going to reuse the name.

    In a different context (e.g. as a type) the same syntax is sometimes used to mean an existential type M[X] forSome { type X }.

    It's unfortunate and confusing that the syntax looks the same, but they're two different, unrelated features. If you're confused about which one a particular use of _ is, maybe check what the compiler/language feature warning is? In my own code I try to always write existential types explicitly (using forSome) to avoid this confusion, but this is just something I came up with, not a rule that libraries tend to follow.