Variance trick with path-dependent types
Here's another one for implicits and path dependent types. I don't understand why I need to be so verbose here: (Note -- I found the answer, see below)
trait B
trait C[X]
trait A { def call[B1 <: B](implicit b: B1): C[B1] }
trait D extends B {
def set(c: C[this.type])开发者_JAVA技巧: Unit
}
first try:
def test1(a: A)(implicit d: D: Unit =
d.set(a.call) // found C[D] -- required C[d.type]
second try:
def test2(a: A)(implicit d: D): Unit =
d.set(a.call[d.type]) // could not find implicit value for parameter b: d.type
third try:
def test3(a: A)(implicit d: D): Unit =
d.set(a.call[d.type](d)) // works. why so much clutter!?
the Scala 2.9 REPL helps us (thanks, whoever added this useful message!). Here for the test1
:
found : C[D]
required: C[d.type]
Note: D >: d.type, but trait C is invariant in type X.
You may wish to define X as -X instead. (SLS 4.5)
d.set( a.call ) // found C[D] -- required C[d.type]
^
Thus: changing trait C[ X ]
to trait C[ -X ]
makes test1
work as expected.
Are you sure you want this.type
? Scala's "this type" is not the same as what is more commonly known as "MyType". See this discussion on this.type
, as well as the discussion linked by the MyType question.
精彩评论