Scala has a nice feature to infer type parameter inside the pattern match. It also checks pattern match exhaustiveness. For example:
sealed trait PField[T]
case object PField1 extends PField[String]
case object PField2 extends PField[Int]
def getValue[X](f: PField[X]): X = f match {
case PField1 => "aaa"
case PField2 => 123
}
Is it possible to achieve the same but using type members instead of type parameters?
sealed trait Field {
type T
}
case object Field1 extends Field {
type T = String
}
case object Field2 extends Field {
type T = Int
}
Following solutions do not work (Tested in Scala 2.12.6):
//No exhaustiveness check
def getValue[X](f: Field {type T = X}): X = f match {
case Field1 => "aaa"
// case Field2 => 123
}
//casting needed
def getValue2[X](f: Field {type T = X}): X = (f: Field) match {
case Field1 => "aaa".asInstanceOf[X]
case Field2 => 123.asInstanceOf[X]
}
type Generified[X] = Field {type T = X}
//No exhaustiveness check
def getValue3[X](f: Generified[X]): X = f match {
case Field1 => "aaa"
// case Field2 => 123
}
Type parameter is really problematic in my case because I have many sub-hierarchies of Fields and each hierarchy have some type classes. I can't put all the needed dependencies inside case object's because they are exported in a thin JAR to clients.
UniqGuarantee
as abbreviation of the phrase "uniqueness guarantee". I omitted the ending of the first word, because everything in that posting was a bit too long. :) – Kitkitchen