Rough Notes on Scala Existential

Summary

This article is the summary of my understanding of the articles written by others. I might have reproduced some of the paragraphs as they were. Please refer to the references section for the full articles.

Existential types are ways of abstracting over types where they are not specified but knowing they are there. In other words, variables as references to the unknown type . Most importantly, existential types would not have existed if it is not for Java wildcards.

Iterator[T] forSome { type T } is equivalent to Iterator<?> in Java.

Iterator[T] forSome { type T <: Number } is equivalent to Iterator<? extends Number> in Java.

Raw types, as in pre-Java 5 libraries, had no type parameter. Existential types are not raw types. They are safer because they stop the compiler instead of letting the compiled code to blow up during execution by throwing runtime exception.

In Scala, Array[T] forSome { type T } is an existential type. It is an array of T where T is some completely unknown type. All that is to T is that it exists at all. This assumption is weak but it means Array[T] at the very least indeed an Array and not an Apple.

Array[T] forSome { type T } matches Array of any type. This is to say foo(arr: Array[T] forSome { type T }) can be written as foo(arr: Array[_]) which also can be written as foo[T](arr: Array[T])

Array[T forSome { type T }], on the other hand, is equivalent to Array[Any] which takes only Array[Any] because Array[A] is defined with an invariant type parameter unlike List[+A] is defined with a covariant type parameter.

More Examples

Map[Class[T forSome { type T }], String] is equivalent to Map[Class[Any], String]. This map only accepts classOf[Any] as keys.

Map[Class[T] forSome { type T }, String] is probably what we want. It accepts keys of Class type i.e. classOf[String], classOf[Int],....

Map[Class[T], String] forSome { type T } matches a map such that once T is defined the rest of the keys must be of same type e.g. if T is String, the rest of the keys must be classOf[String].

// Tested working as of Scala 2.11.x

var a: List[Class[_]] = List(classOf[Int],classOf[String])
var b: List[Class[_]] = List(classOf[String],classOf[String])
var c: List[Class[_]] = List(classOf[Any],classOf[Any])

// var d: List[Class[T forSome{type T}]] = List(classOf[Int],classOf[String]) // compile error
// var e: List[Class[T forSome{type T}]] = List(classOf[String],classOf[String]) // compile error
var f: List[Class[T forSome{type T}]] = List(classOf[Any],classOf[Any])

var g: List[Class[T] forSome{type T}] = List(classOf[Int],classOf[String])
var h: List[Class[T] forSome{type T}] = List(classOf[String],classOf[String])
var i: List[Class[T] forSome{type T}] = List(classOf[Any],classOf[Any])

// var j: List[Class[T]] forSome{type T} = List(classOf[Int],classOf[String]) // compile error
var k: List[Class[T]] forSome{type T} = List(classOf[String],classOf[String])
var l: List[Class[T]] forSome{type T} = List(classOf[Any],classOf[Any])

References

  1. Scala’s existential types. Further down the tread Martin mentioned Scala existential would not have existed if not for Java wildcards.
  2. Existential types in Scala
  3. Existential types are not raw types
  4. Returning the “Current” Type in Scala. Using F-bound type effectively in Scala and why Typeclass is a better solution than F-bound in Scala.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s