I am using the "case class instead of Enumeration" pattern, and want to have a list of all values per "enumeration" as well as a few methods. So I decided to not just derive my case classes from a sealed abstract class, but to derive all the sealed abstract classes from a superclass called Lookup, and to define a LookupTrait from which to derive the abstract classes' companion objects.
abstract class Lookup {
val name: String
override def toString = name
}
trait LookupTrait[T<:Lookup] {
val all: Map[String, T]
val default: T
def withName(name: String): T =
if(all.contains(name)) all(name)
else default
}
And an example lookup looks like this:
sealed case class StudyGoal(override val name: String) extends Lookup
object StudyGoal extends LookupTrait[StudyGoal] {
override val all = Map(
"present new evaluation method" -> StudyGoal("present new evaluation method"),
"evaluate existing product" -> StudyGoal("evaluate existing product"),
"develop new theoretical model" -> StudyGoal("develop new theoretical model"),
"unknown" -> StudyGoal("unknown")
)
override val default = StudyGoal("unknown")
}
I would prefer to simply define a list of strings in the companion object of each lookup and have the trait instantiate the case classes. But while I found three different ways of doing reflection in Scala - using a Manifest, a TypeTag, and getting the constructor of a class as described in the documentation, all of them seem to require to have an instance of the class present, and I couldn't get them to work within the parameterized LookupTrait trait.
I would like to have something like:
abstract class Lookup {
val name: String
override def toString = name
}
trait LookupTrait[T<:Lookup] {
val allNames: List[String]
val default: T = //Instantiate a T using the string "unknown".
//It is OK that this string will be the same for all Lookups.
val all: Map[String, T] = allNames.map(
n => n -> //instantiate a T here, using n as the parameter
) += default
def withName(name: String): T =
if(all.contains(name)) all(name)
else default
}
sealed case class StudyGoal(override val name: String) extends Lookup
object StudyGoal extends LookupTrait[StudyGoal] {
override val allNames = List(
"present new evaluation method"),
"evaluate existing product",
"develop new theoretical model"
)
}
Aucun commentaire:
Enregistrer un commentaire