提取使用宏进入特征的ADT基本逻辑

Eri*_*lun 5 macros scala dry abstract-data-type scala-2.11

我最近偶然发现了Travis Brown @ Iteration在Scala中的一个密封特性上的一段相当棒的代码.它通过允许枚举ADT"构造函数"(用Haskell的术语)将Scala 基于sealed trait+ case class/object的ADT转换为更接近真实枚举的东西.所以我删除了Travis代码生成的3个弃用警告中的2个,最后是http://pastebin.com/L1gYGJWh,然后我按如下方式使用:

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)
}
Run Code Online (Sandbox Code Playgroud)

但是,我很快就需要重用相同的withName逻辑,所以我尝试编写以下ADT基本特征:

trait ADT[T] {
  def all: Set[T] = enumerate[T]

  def withName(name: String): Option[T] =
    all.find(_.toString === name)
}
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译:

Can only enumerate values of a sealed trait or class
Run Code Online (Sandbox Code Playgroud)

虽然我理解为什么会出现这种错误,但我并不知道如何告诉类型系统"推迟"检查直到实际继承的东西ADT.

这是否可能与Scala 2.11.2中的当前宏系统一样,或者我是否必须找到(部分)解决方法?