I recently stumbled on a rather awesome piece of code from Travis Brown @ Iteration over a sealed trait in Scala?. It turns Scala's sealed trait
+ case class/object
based ADTs into something that is closer to true enums by allowing enumeration of the ADT "constructors" (in Haskell's terms). So I removed 2 of the 3 deprecation warnings Travis' code was producing and ended up with http://pastebin.com/L1gYGJWh which I then used as follows:
sealed trait KeywordType
case object Crime extends KeywordType
case object Gambling extends KeywordType
case object Porn extends KeywordType
object KeywordType {
/** Maps e.g. "Crime" to Crime */
def withName(x: String): Option[KeywordType] =
adt.enumerate[KeywordType].find(_.toString === x)
}
However, I quickly needed to reuse the same bit of withName
logic so I tried to write the following ADT
base trait:
trait ADT[T] {
def all: Set[T] = enumerate[T]
def withName(name: String): Option[T] =
all.find(_.toString === name)
}
However, this does not compile giving:
Can only enumerate values of a sealed trait or class
Although I understand why this error occurs, I do not have a clue as to how to go about telling the type system to "defer" that check until something actually inherits from ADT
.
Is this even possible with the current macro system in Scala 2.11.2 or do I have to find a (partial) workaround?