假设:
scala> sealed trait Parent
defined trait Parent
scala> case object K extends Parent
defined object K
scala> case object J extends Parent
defined object J
scala> sealed trait Result
defined trait Result
scala> case object KResult extends Result
defined object KResult
scala> case object JResult extends Result
defined object JResult
如何实施以下F
?
scala> def f[A <: Parent, B <: Result](x: A): B = ???
f: [A <: Parent, B <: Result](x: A)B
我们假设K
必须有KResult
,J
有JResult
。
但是,我担心的是在编译时传递f[K, JResult]
没有强制约束。
或许,我可以简单地诉诸:
def f(x: Parent): Result = x match {
case K => KResult
case J => JResult
但是,这种做法的弱点在于我可能会犯错:
def badF(x: Parent): Result = x match {
case K => JResult
case J => KResult
答案 0 :(得分:1)
您需要一种方法在类型系统中将KResult
与K
相关联。您可以通过向A
添加类型参数Result
来实现这一目标(可选地,它可以具有Parent
的上限,但这可能不是必需的。)
sealed trait Parent
case object K extends Parent
case object J extends Parent
sealed trait Result[A]
case object KResult extends Result[K.type]
case object JResult extends Result[J.type]
然后,B
可以被Result[A]
限制,这将强制执行以下事实:A = K
,然后是B <: Result[K]
。
def f[A <: Parent, B <: Result[A]](x: A): B = ???
scala> f[K.type, Result[J.type]](K)
<console>:16: error: type arguments [K.type,Result[J.type]] do not conform to method f's type parameter bounds [A <: Parent,B <: Result[A]]
f[K.type, Result[J.type]](K)
^
这种方法虽然没有多大意义,但由于无法推断结果类型,因此必须手动提供。不过,这就是你如何强制执行这些限制。