2015-03-09 5 views
4

У меня есть компилятор Тип ошибки несоответствия, что я не понимаю.Тип несоответствие с проекцией типа

Учитывая следующее определение 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) ^

+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 даже не в области на месте ошибки - кажется, есть lea выкрикнул. Кажется, что Scala не выполняет замену R = Int внутри уточнения, позволяя оставить параметр R.

+1

[Я сделал проблему для этого] (https://issues.scala-lang.org/browse/SI-9222), поэтому мы увидим, согласны ли люди с тем, что это ошибка. – Owen