键入与类型投影不匹配

时间:2015-03-09 15:12:48

标签: scala path-dependent-type type-projection

我有一个我不明白的编译器类型不匹配错误

鉴于Elem和工厂(Companion)的以下定义:

object Elem {
  trait Companion[E[~] <: Elem[~]] {
    def apply[S](peer: E[S]#Peer): E[S] // wrap a peer in its elem
  }
}
trait Elem[S] {
  type Peer
}

例如,Obj具有属性和对等类型Expr

trait Expr[S, A]

trait Obj[S] {
  // query an attribute by key
  def attr[E[~] <: Elem[~]](key: String)
                           (implicit c: Elem.Companion[E]): Option[E[S]#Peer]
}

我应该能够做到以下几点:

// process elements with peer `Expr[~, A]`
trait Impl[S, A, E[~] <: Elem[~] { type Peer = Expr[~, A] }] {
  implicit def companion: Elem.Companion[E]

  def test(obj: Obj[S]): Unit =
    obj.attr[E]("foo").fold(()) { ex =>
      val newElem = companion[S](ex)
    }
}

这最后一位因错误消息而失败:

<console>:62: error: type mismatch; found : E[S]#Peer (which expands to) Expr[S,A] required: E[S]#Peer (which expands to) Expr[S,A] val newElem = companion[S](ex) ^

1 个答案:

答案 0 :(得分:4)

我将您的示例缩减为以下内容:

trait Elem {
    type Peer
}

trait Impl[E[~] <: Elem {type Peer = ~}] {
    def foo[R](peer: E[R]#Peer)

    foo[Int](??? : E[Int]#Peer)
}

scalac给出

Error:(12, 18) type mismatch;
 found   : this.scala.Peer
    (which expands to)  Int
 required: this.Peer(in method foo)
    (which expands to)  R
    foo[Int](??? : E[Int]#Peer)
             ^^

我不确定,但这看起来像是一个Scala错误,因为R甚至不在错误网站的范围内 - 它似乎已泄露出来。 Scala似乎未能在细化内执行替换R = Int,允许参数R保留。