5

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?

Community
  • 1
  • 1
Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111
  • 2
    For what it's worth, I just took a shot at solving this in a more principled way with Shapeless and ran into [some weird behavior](http://stackoverflow.com/q/25838411/334519). – Travis Brown Sep 14 '14 at 21:59

0 Answers0