scalascala-2.9multiple-constructorsgenerics

Scala: Generic class with multiple constructors


I'm trying to create a generic class like this:

class A[T](v: Option[T]) {
  def this(v: T) = this(Some(v))
  def this() = this(None)
  def getV = v 
}

Then I do some testing:

scala> new A getV
res21: Option[Nothing] = None
scala> new A(8) getV
res22: Option[Int] = Some(8)

So far so good. But as soon as I try to call the main constructor, I get this:

scala> new A(Some(8)) getV
<console>:9: error: ambiguous reference to overloaded definition,
both constructor A in class A of type (v: T)A[T]
and  constructor A in class A of type (v: Option[T])A[T]
match argument types (Some[Int])
       new A(Some(8)) getV
       ^

scala> new A(None) getV
<console>:9: error: ambiguous reference to overloaded definition,
both constructor A in class A of type (v: T)A[T]
and  constructor A in class A of type (v: Option[T])A[T]
match argument types (None.type)
       new A(None) getV
       ^

What's so "ambiguous" between those two constructors? Or (let me guess) it's yet another thing I do not know about Scala's type system? :)

Sure, if I use non-generic class everything works as expected. My B class works just fine:

class B(v: Option[String]) {
  def this(v: String) = this(Some(v))
  def this() = this(None)
  def getV = v 
}

scala> new B("ABC") getV
res26: Option[String] = Some(ABC)
scala> new B getV
res27: Option[String] = None
scala> new B(Some("ABC")) getV
res28: Option[String] = Some(ABC)
scala> new B(None) getV
res29: Option[String] = None

Solution

  • The new A(Some(8)) can be either:

    You can specify the type explicitly, like new A[Int](Some(8)).