6
votes

When I tried to write a class that accepts any Class[_] as a parameter:

case class A(klass: Class[_])

I got this error:

test.scala:1: warning: inferred existential type Option[Class[_$1]] forSome { type $1 }, which cannot be expressed by wildcards, should be enabled by making the implicit value scala.language.existentials visible. This can be achieved by adding the import clause 'import scala.language.existentials' or by setting the compiler option -language:existentials. See the Scala docs for value scala.language.existentials for a discussion why the feature should be explicitly enabled. case class A(klass: Class[]) ^ one warning found

I'm willing to know why it doesn't work. But where is "the Scala docs for value scala.language.existentials"? I googled "scaladoc scala.language.existentials" but got some threads I can't understand.

Clarification: I know the 'correct' way to implement such a class is:

case class A[T](klass: Class[T])

But I want to know what the warning message means.

3

3 Answers

4
votes

In this case what you're looking for is a ClassTag:

class A[T](implicit val tag : reflect.ClassTag[T])

This gives you the ClassTag object for the generic parameter that you can use to access the Class given when objects are being created.

As for existentials, you can check:

3
votes

Heather Miller just explained on scala-user that you use the left-hand pane's search for "language", and then the right-hand pane's search for existential, since the left pane doesn't do members.

If you find a discussion you don't understand, then you know you're in the right place.

3
votes

I had the same question and I hit this SO thread; none of the answers are a direct answer to the question, so I'll add it below. The Scala docs for value scala.language.existentials are probably in the JavaDoc comments, which state:

 /** Only where enabled, existential types that cannot be expressed as wildcard
   *  types can be written and are allowed in inferred types of values or return
   *  types of methods. Existential types with wildcard type syntax such as `List[_]`,
   *  or `Map[String, _]` are not affected.
   *
   *  '''Why keep the feature?''' Existential types are needed to make sense of Java’s wildcard
   *  types and raw types and the erased types of run-time values.
   *
   *  '''Why control it?''' Having complex existential types in a code base usually makes
   *  application code very brittle, with a tendency to produce type errors with
   *  obscure error messages. Therefore, going overboard with existential types
   *  is generally perceived not to be a good idea. Also, complicated existential types
   *  might be no longer supported in a future simplification of the language.
   *
   *  @group production
   */
  implicit lazy val existentials: existentials = languageFeature.existentials