I'm having a compiler type mismatch error that I do not understand.
Given the following definition of an Elem
and a factory (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
}
And given for example an Obj
with attributes and a peer type 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]
}
I should be able to do the following:
// 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)
}
}
This last bit fails with the brilliant error message:
<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)
^