Why does this not compile?
The error given is class SomeElement needs to be abstract, since method eval in trait Element of type [T <: Typed]=> scala.util.Try[T] is not defined
I cannot understand why the method eval
defined on SomeElement does not satisfy the type constraints.
As I understand it, eval
should return something wrapped in a Try
which subclasses Typed
.
Try is covariant in its type parameter. The implementation of eval
in SomeElement
returns a NumberLike
, and NumberLike
subclasses Typed
. So what's gone wrong?
import scala.util.Try
trait Element {
def eval[T <: Typed]: Try[T]
}
trait Typed
case class NumberLike(n: Long) extends Typed
case class SomeElement(n: Long) extends Element {
def eval = Try {
NumberLike(n)
}
}
object app extends Application {
println (SomeElement(5).eval)
}
Trying to add an explicit type parameter to eval in SomeElement
doesn't help either:
case class SomeElement(n: Long) extends Element {
def eval[NumberLike] = Try {
NumberLike(n)
}
}
Changing the defintion of SomeElement to the above gives:
found : <empty>.NumberLike
required: NumberLike(in method eval)
NumberLike(n)
EDIT I would really like to know why this doesn't compile. Workarounds for the problem are helpful, but I really want to know what's going on here.
The type parameter T
being defined on the function, not on the enclosing type Element
, it can't be 'erased' by inheritance and must be kept on the overriding function (http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#class-members).
Moving the type parameter to Element
definition make it work as following.
trait Element[T <: Typed] {
def eval: Try[T]
}
trait Typed
case class NumberLike(n: Long) extends Typed
case class SomeElement(n: Long) extends Element[NumberLike] {
def eval = Try {
NumberLike(n)
}
}
Or using a type member:
trait Element {
type T <: Typed
def eval: Try[T]
}
trait Typed
case class SomeElement(n: Long) extends Element {
type T = NumberLike
def eval = Try {
NumberLike(n)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With