I always thought that context bounds and implicit parameter lists behaved exactly the same, but apparently not.
In the example below, I expect summon1[Int]
and summon2[Int]
to return the same type, but they don't. I expected summon2[Int]
to return a path dependent type, but instead it gives me a type projection. Why?
Welcome to the Ammonite Repl 2.2.0 (Scala 2.13.3 Java 11.0.2)
@ trait Foo[A] {
type B
def value: B
}
defined trait Foo
@ implicit def fooInt = new Foo[Int] {
override type B = String
override def value = "Hey!"
}
defined function fooInt
@ implicit def fooString = new Foo[String] {
override type B = Boolean
override def value = true
}
defined function fooString
@ def summon1[T](implicit f: Foo[T]) = f.value
defined function summon1
@ def summon2[T: Foo] = implicitly[Foo[T]].value
defined function summon2
@ summon1[Int]
res5: String = "Hey!"
@ summon2[Int]
res6: Foo[Int]#B = "Hey!"
@
summon1
works because there is a path to the type, via thef
handle, but insummon2
there isn't. Got it 👍 – Panfish