-
Notifications
You must be signed in to change notification settings - Fork 527
Open
Labels
Description
Suppose we are creating a XML processing library, we want to ensure all the methods in a XML document only applies to elements that belong to the document.
We can define the document type like this:
trait Element[Owner <: Document with Singleton]
trait Document {
def createElement(): Element[this.type]
def appendChild(element: Element[this.type]): Unit
}However, this approach is problematic when we summon the document for an element:
import shapeless._
def appendToDocument[Owner <: Document with Singleton](
element: Element[Owner])(
implicit witnessOwner: Witness.Aux[Owner]) = {
witnessOwner.value.appendChild(element)
}cmd2.sc:11: type mismatch;
found : Helper.this.Element[Owner]
required: Helper.this.Element[shapeless.Witness.<refinement>.type]
Note: Owner >: shapeless.Witness.<refinement>.type, but trait Element is invariant in type Owner.
You may wish to define Owner as -Owner instead. (SLS 4.5)
witnessOwner.value.appendChild(element)
^
The problem is that Scala compiler does not know Element[witnessOwner.value.type] and Element[Owner] are the same type.
This problem can be resolved if we add a value.type =:= T evidence in Witness, along with the ability of substitution in Scala 2.13.