种类不符合lambda类型

0__*_*0__ 5 types scala existential-type type-kinds partially-applied-type

遇到类型"种类"的问题:

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] = ???
Run Code Online (Sandbox Code Playgroud)

这失败了

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] = ???
                                  ^
Run Code Online (Sandbox Code Playgroud)

声明的边界有什么问题?我是否需要将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]} = ???
Run Code Online (Sandbox Code Playgroud)

Owe*_*wen 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
Run Code Online (Sandbox Code Playgroud)

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

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

def t: MemberNeedsA { type T[S <: B] }
def u: MemberNeedsB { type T[S <: A] }
Run Code Online (Sandbox Code Playgroud)

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

def s: MemberNeedsA with MemberNeedsB
Run Code Online (Sandbox Code Playgroud)

也许这种交集实际上不可能存在于自然界中,但 Scala 不会检查这一点。

好的,但这与你的问题不太相关。回到你的问题:我认为你有一个差异问题。您想test给调用者返回一个Attr,并且 anAttr拥有一个类型函数 ( A[_]),并且您想说,this 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] = ...
Run Code Online (Sandbox Code Playgroud)

A[_]但解决方案将取决于对 的论证的限制的意图。