我最近偶然发现了来自 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)
}
但是,我很快需要重用相同的withName
逻辑,所以我尝试编写以下ADT
基本特征:
trait ADT[T] {
def all: Set[T] = enumerate[T]
def withName(name: String): Option[T] =
all.find(_.toString === name)
}
但是,这并不能编译给出:
Can only enumerate values of a sealed trait or class
尽管我理解为什么会发生此错误,但我不知道如何告诉类型系统“推迟”该检查,直到某些东西实际继承自ADT
.
Scala 2.11.2 中的当前宏系统甚至可以做到这一点,还是我必须找到(部分)解决方法?