【问题标题】:Matching type constraints in Scala failsScala 中的匹配类型约束失败
【发布时间】:2012-10-13 04:12:55
【问题描述】:

我正在尝试在 Scala 2.9.2 中创建一个地图包装器,其值具有特定的更高种类的类型,并且正在与类型系统搏斗。下面是代码的简化版本来说明问题:

trait A

trait B[C] {
  def c: C
}

trait E[C <: B[C], D <: A]

case class MyMap[M <: A, L <: B[L], N[L, M]](map: Map[M, N[L, M]])

object MyMap {
  def empty[M <: A, L <: B[L], N[L, M]] = MyMap(Map.empty[M, N[L, M]])
}

val myMap = MyMap.empty[A, T forSome { type T <: B[T] }, E]

当我尝试编译它时,最后一条语句失败并出现编译器错误,表明我没有匹配类型边界。但是在我看来,我是这样的,也许在我有 N[L, M] 和以前的 L <: b n m l :>

类型参数的种类 (A,T forSome { type T <: b m l n e c>:Nothing :Nothing :Nothing : Nothing <: any>

val myMap = MyMap.empty[A, T forSome { type T <: b e>

感谢您的任何建议。

谢谢-

【问题讨论】:

    标签: scala


    【解决方案1】:

    第二个参数有一个问题,第三个参数有一个问题。我不知道第二个参数,我不确定existentia 在这里可以允许什么。所以这只是第三个参数的问题。

    有同样错误的更简单的代码:

    class A {}
    
    class C[X <: A] {}
    
    def f[X[_]] = 12
    
    f[List]
    res1: Int12
    f[C]
    error: kinds of the type arguments (C) do not conform to 
    the expected kinds of the type parameters (type X).
    C's type parameters do not match type X's expected parameters: 
        type X's bounds >: Nothing <: A are stricter 
        than type _'s declared bounds >: Nothing < : Any
           f[C]
             ^
    

    很简单,方法 empty 期望作为第三个类型参数的泛型类型具有两个参数并且没有限制。在空的正文中,您可以写N[Int, String] 或其他任何内容。类型E,有一些约束,与此不兼容(注意:我发现writing N[L,M]而不是N[_, _],与LM前面类型参数的名称有点误导。或者也许这表明您并不真正想要更高阶的类型参数)。

    如果你写在上面的代码中

    def g[X[_ <: A]] = 13
    

    然后调用g[C] 就可以了(g[List] 也可以,应该这样,那里不会发生任何错误)。

    同样,如果为空,您的代码也可以工作(前提是您传递了合适的第二个参数)

    Map.empty[M <: A, L <: B[L], N[X <: B[X], Y <: A]]
    

    【讨论】:

    • 感谢您的快速响应。使用您的示例和我的特征 B,如果 C 被定义为 class C[X &lt;: B[X]] {},那么您将如何定义函数 g?
    • def g[X[Y <: b>
    • 谢谢。那么,如果我想要列出这些 C 的列表,并且没有比 C 更多的限制(我认为这是我们将其剥离后我遇到的真正问题)。我试过val l = List[C[T forSome { type T &lt;: B[T] } ](),它抱怨“类型参数 [T forSome { type T <: b c>
    最近更新 更多