我最近偶然发现了来自Travis Brown @ Iteration over a sealed trait in Scala?的一段相当棒的代码。它通过允许枚举ADT"构造函数"将基于Scala的基于sealed trait
+ case class/object
的ADT变成更接近真实枚举的东西。 (用Haskell的术语来说)。所以我删除了3个弃用警告中的2个Travis'代码正在生成并以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
虽然我理解为什么会出现这种错误,但我并不清楚如何告诉类型系统“推迟”#34;检查直到某些内容真正继承自ADT
。
Scala 2.11.2中的当前宏系统是否可以实现这一点,还是必须找到(部分)解决方法?