只允许ADT使用`case object`

时间:2015-10-19 15:43:57

标签: scala

给定代数数据类型:

scala> sealed trait XYZ 
defined trait XYZ

scala> case object X extends XYZ
defined object X

scala> case class Y(name: String) extends XYZ
defined class Y

我试图定义一个方法:

def f(a: ?): String

接受代数数据类型,例如:XYZ,但仅编译,如果其所有子项都是case object

因此,在上面的例子中,我希望XYZ无法编译。

如何仅使用compile-time检查来编写此函数?

1 个答案:

答案 0 :(得分:6)

限制单身人士:

scala> sealed trait T ; case object X extends T ; case class Y(y: String) extends T
defined trait T
defined object X
defined class Y

scala> def f[A <: Singleton](a: A) = a.toString
f: [A <: Singleton](a: A)String

scala> f(X)
res0: String = X

scala> f(Y("hi"))
<console>:15: error: inferred type arguments [Y] do not conform to method f's type parameter bounds [A <: Singleton]
       f(Y("hi"))
       ^
<console>:15: error: type mismatch;
 found   : Y
 required: A
       f(Y("hi"))
          ^

抱歉,您问过这个问题:

scala> sealed trait T { this: Singleton => } ; case object X extends T ; case class Y(y: String) extends T
<console>:11: error: illegal inheritance;
 self-type Y does not conform to T's selftype T with Singleton
       sealed trait T { this: Singleton => } ; case object X extends T ; case class Y(y: String) extends T
                                                                                                         ^