And*_*ate 6 polymorphism types scala subtype type-parameter
我试图用非常通用的类型参数参数化一些方法.
举个例子,我在REPL中首先定义:
trait Term
case class FunctionalTerm[+T <: Term](t: T) extends Term
Run Code Online (Sandbox Code Playgroud)
直观地说,下面的方法采用Term和FunctionalTerm,并返回类型为传递的术语类型的最小上限和FunctionalTerm的参数类型的东西:
def ex1[T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3): R = sys.error("TODO")
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
尝试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)
^
Run Code Online (Sandbox Code Playgroud)
我花了大约两天时间试图找出解决方案,现在我完全陷入困境.我在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)
Run Code Online (Sandbox Code Playgroud)
引入额外参数X
似乎会导致问题.我可以在REPL中定义以下内容:
def ex3[T1 <: Term, FunctionalTerm[T1] <: X, X <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex3")
Run Code Online (Sandbox Code Playgroud)
但是试图随后定义:
def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2)
Run Code Online (Sandbox Code Playgroud)
给出错误:
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)
^
Run Code Online (Sandbox Code Playgroud)
所以,我想问题就变成了:为什么X
签名中未使用的参数会产生这种效果?
我不确定你是否遇到了一个bug,但我很确定你的生活会变得更加困难.你可以依靠协方差和统一来为你做所有艰苦的工作,
scala> trait Term
defined trait Term
scala> case class FunctionalTerm[+T <: Term](t: T) extends Term
defined class FunctionalTerm
scala> def ex1[T <: Term](t1 : FunctionalTerm[T], s : T) : T = s
ex1: [T <: Term](t1: FunctionalTerm[T], s: T)T
scala> class A extends Term ; class B extends A ; class C extends A
defined class A
defined class B
defined class C
scala> ex1(new FunctionalTerm(new B), new C)
res0: A = C@4ceeb514
Run Code Online (Sandbox Code Playgroud)
请注意,推断的结果类型(相当于R
原来的更复杂的定义)......这A
是的LUB B
和C
.
现在翻转的版本是微不足道的,Just Works,
scala> def ex2[T <: Term](s : T, t1 : FunctionalTerm[T]) : T = s
ex2: [T <: Term](s: T, t1: FunctionalTerm[T])T
scala> ex2(new C, new FunctionalTerm(new B))
res1: A = C@522ddcec
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
792 次 |
最近记录: |