给出以下AST Success和Failure:
sealed trait Success
case object FooGood extends Success
case object BarGood extends Success
sealed trait Failure
case object FooBad extends Failure
case object BarBad extends Failure
Run Code Online (Sandbox Code Playgroud)
方法签名:
def go[A <: Failure, B <: Success](x: Int): Either[A, B] = ???
Run Code Online (Sandbox Code Playgroud)
但是,我想约束Left和Right类型特定于Foo或Bar.
但是下面的代码编译(违背我的意愿):
scala> go[FooBad.type, BarGood.type](5)
scala.NotImplementedError: an implementation is missing
Run Code Online (Sandbox Code Playgroud)
如何在编译时实现此约束?
您遇到的问题是编译器不知道它与FooGood是否有某种关系FooBad,因此您需要以某种方式提示它。
这是我想出的,尽管我承认它不是很优雅:
trait Grouping[B, G]
object FooHelper {
implicit object fooGrouping Grouping[FooBad.type, FooGood.type]
}
object BarHelper {
implicit object barGrouping Grouping[BarBad.type, BarGood.type]
}
def go[A <: Failure, B <: Success](x: Int)(implicit ev: Grouping[A, B]): Either[A, B] = ???
import FooHelper._
import BarHelper._
// the following two type check
go[FooBad.type, FooGood.type](5)
go[BarBad.type, BarGood.type](5)
// while these two do not
go[FooBad.type, BarGood.type](5)
go[BarBad.type, FooGood.type](5)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,提示是通过创建 aGrouping并将正确的分组放入隐式范围来实现的。这种方法的问题是用户可能会创建自己的分组,而这可能是无效的。