2

假设我有以下 Scala 代码:

sealed trait Foo
sealed trait Bar
object Foo1 extends Foo
object Foo2 extends Foo
object Foo3 extends Foo
object Bar1 extends Bar
object Bar2 extends Bar
object Bar3 extends Bar
case class Hello(foo:Foo, bar:Bar)

val a = Hello(Foo1, Bar2) // allowed
val b = Hello(Foo2, Bar2) // suppose not allowed 

如果将任何不兼容的组合应用于Hello. 假设只允许以下组合:(Foo1, Bar1)(Foo1, Bar2)和。(Foo2, Bar3)(Foo3, Bar3)

是否可以在编译时进行测试?我意识到插件可能允许我这样做。一些提示将不胜感激。上述教程对于最新版本的 Scala (2.11.x) 似乎已经过时,因此指向其他教程的指针也很棒。

在实际示例中,大约有 10 个 和 的实例,Foo总共Bar有 100 种组合,其中大约一半无效。此外,有效组合将来可能会任意更改。

编辑

实际问题要复杂一些。该Hello方法采用Seq如下方式:

case class Hello(foos:Seq[Foo], bars:Seq[Bar]) 

复杂标准的示例包括:

  1. 如果foos包含Foo1bars不能有Bar1
  2. foos不能包含Foo1Foo3在一起。

代码示例:

Hello(Seq(Foo1), Seq(Bar2, Bar3)) // valid 
Hello(Seq(Foo1, Foo3), Seq(Bar1)) // invalid due to rule 2
4

1 回答 1

4

类型有一个技巧,不确定它是否非常漂亮(一点也不漂亮),并且您必须手动编写很多这样的规则,但是您不需要使用繁重的插件/库:

trait Validator[F, S] { }
object Validator {
    implicit object firstPair extends Validator[Foo1.type, Bar1.type]
    implicit object secondPair extends Validator[Foo1.type, Bar2.type]
    implicit object thirdPair extends Validator[Foo2.type, Bar3.type]
    implicit object fourthPair extends Validator[Foo3.type, Bar3.type]
}

case class Hello[F <: Foo, S <: Bar](foo: F, bar: S)(implicit v: Validator[F, S])

val a = Hello(Foo1, Bar2) // allowed
val b = Hello(Foo2, Bar2) // break in compile time
于 2015-03-31T06:41:21.780 回答