I try to define a type constraint with abstract type. but unfortunately, it doesn't compile.
sealed trait MatchableValue {
type A
def value: A
def asSingleItemValue : ItemValue
}
sealed trait ItemValue {
type A
def value: A
}
case class StringValue(value: String) extends ItemValue {type A = String}
case class StringMatchableValue(value: String) extends MatchableValue{
type A = String
override def asSingleItemValue = StringValue(value)
}
Unfortunately, this one doesn't work
def asSingleItemValue[B <: ItemValue](implicit ev: A =:= B#A) : B
The aim of the type constraint is to be warned at compile-time of such an error :
case class IntValue(value: Int) extends ItemValue {type A = Int}
case class IntMatchableValue(value: Int) extends MatchableValue{
type A = Int
def asSingleItemValue = StringValue("error")
}
You can accomplish this with a type refinement (note the method's return type):
Now this compiles:
But this doesn't:
Which I believe is what you want.
It's also worth noting that the following is a common pattern when dealing with type refinements:
This does exactly the same thing, but the syntax is a nice alternative if you find yourself needing to write out the type refinement a lot.