5

“种类”类型有问题:

trait Sys[ S <: Sys[S]]
trait Expr[S <: Sys[S], A]
trait Attr[S <: Sys[S], A[_]]
def test[  S <: Sys[S]]: Attr[S, ({type l[x<:Sys[x]]=Expr[x,Int]})#l] = ???

这失败了

error: kinds of the type arguments (S,[x <: Sys[x]]Expr[x,Int]) do not conform
to the expected kinds of the type parameters (type S,type A) in trait Attr.
[x <: Sys[x]]Expr[x,Int]'s type parameters do not match type A's expected parameters:
type x's bounds <: Sys[x] are stricter than type _'s declared bounds >: Nothing <: Any
           def test[S <: Sys[S]]: Attr[S, ({type l[x<:Sys[x]]=Expr[x,Int]})#l] = ???
                                  ^

声明的界限有什么问题?我是否需要将该 cr*ppy 部分应用的类型携带到的类型构造函数中trait Attr?为什么?我可以在不触及 的定义的情况下解决这个问题Attr吗?

我确实需要函数边界test才能使实现工作,但我不想将这些边界扩散到公共接口Attr


注意:如果我使用类型成员(我不想要的),它可以工作:

trait Attr[S <: Sys[S]] { type A[_]}
def test[  S <: Sys[S]]: Attr[S] { type A[S <: Sys[S]] = Expr[S, Int]} = ???
4

1 回答 1

4

正如您所观察到的,在提供更高种类的类型参数时,您不能总是不匹配边界。有趣的是,这实际上是一个方差问题:

class A
class B extends A
trait NeedsNeedsA[T[S <: A]]
trait NeedsNeedsB[T[S <: B]]
trait NeedsA[S <: A]
trait NeedsB[S <: B]

def x: NeedsNeedsA[NeedsB] // fails
def y: NeedsNeedsB[NeedsA] // works

如果您将更高种类的类型视为类型上的函数,这是有道理的,在其参数的范围内是逆变的。

有趣的是,在表面上很像子类型的结构类型中,Scala 并没有给出相同的错误:

def t: MemberNeedsA { type T[S <: B] }
def u: MemberNeedsB { type T[S <: A] }

原因是结构类型有点像交集:

def s: MemberNeedsA with MemberNeedsB

并且可能该交集实际上并不存在于自然界中,但 Scala 并没有对此进行检查。

好的,但这与您的问题无关。回到你的问题:我认为你有一个差异问题。你想test给调用者一个Attr,并且 anAttr拥有一个类型函数 ( A[_]),你想说, Attr有一个需要更具体参数的类型函数。我想你可以明白为什么你不应该被允许这样做——这与你不能用一个需要更具体参数的函数来代替需要更一般参数的函数的原因是一样的。

在这一点上,恐怕解决方案将不得不取决于您希望Attr能够完成什么。您需要弄清楚为什么在某些情况下比其他情况更需要限制类型参数。如果“某些Attrs 比其他 s 更具限制性”在您的程序中具有概念意义,您可以定义:

trait Attr[S <: Sys[S], B[Y <: B[Y]], A[X <: B[X]]]
def test[S <: Sys[S]]: Attr[S, Sys, L] = ...

但是解决方案将取决于对A[_]' 论点的限制是什么意思。

于 2013-01-18T02:39:42.810 回答