我正在尝试使用非常通用的类型参数参数化一些方法。
例如,在 REPL 中我首先定义:
trait Term
case class FunctionalTerm[+T <: Term](t: T) extends Term
直观地说,以下方法接受一个 Term 和一个 FunctionalTerm,并返回类型为传递的 term 类型的最小上限和 FunctionalTerm 的参数类型的东西:
def ex1[T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3): R = sys.error("TODO")
到目前为止,在 REPL 中表现出色。
然后我定义ex2
为一个便利函数,它执行与 相同的操作ex1
,但交换了输入参数:
def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2,s)
尝试ex2
在 REPL 中定义会出现以下错误:
error: inferred type arguments [T2,T3,FunctionalTerm,T3,T3] do not conform to method ex1's type parameter bounds [T1 <: Term,T3 <: X,FunctionalTerm[T1] <: X,X <: R,R <: Term]
ex1(t2,s)
^
error: type mismatch;
found : FunctionalTerm[T2]
required: FunctionalTerm[T1]
ex1(t2,s)
^
error: type mismatch;
found : T3(in method ex2)
required: T3(in method ex1)
ex1(t2,s)
^
error: type mismatch;
found : R(in method ex1)
required: R(in method ex2)
ex1(t2,s)
^
我花了大约两天的时间试图找出解决方案,现在完全被卡住了。我在 Google 上找不到更多信息。
由于 的 类型参数列表与ex2
的 相同,ex1
但使用T1
和T2
交换,我不明白是错误的,或者如何修复它。
任何帮助将不胜感激!
更新
最小的上限是红鲱鱼。这个例子可以进一步提炼。
可以在 REPL 中定义以下两个函数而不会出错:
def ex1[T1 <: Term, FunctionalTerm[T1] <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex1")
def ex2[T2 <: Term, FunctionalTerm[T2] <: Term](t2: FunctionalTerm[T2]): Term = ex1(t2)
引入额外的参数X
似乎会导致问题。我可以在 REPL 中定义以下内容:
def ex3[T1 <: Term, FunctionalTerm[T1] <: X, X <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex3")
但试图随后定义:
def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2)
给出错误:
error: inferred type arguments [T2,FunctionalTerm,Nothing] do not conform to method ex3's type parameter bounds [T1 <: Term,FunctionalTerm[T1] <: X,X <: Term]
def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2)
^
error: type mismatch;
found : FunctionalTerm[T2]
required: FunctionalTerm[T1]
def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2)
^
所以,我猜问题就变成了:为什么X
签名中未使用的参数会有这种效果?