Reputation: 20080
I am trying to provide some typeclasses implementations which involves higher kinded types, as in the following code:
trait Blah[A,B] {
def apply(b:B):List[A]
}
object Blah {
implicit def blah1[A,B<:List[A]]:Blah[A,B] = new Blah[A,B]{
def apply(b:B):List[A] = b
}
implicit def blah2[A,B](implicit ev: B<:<List[A]):Blah[A,B] = new Blah[A,B]{
def apply(b:B):List[A] = b
}
}
object Stuff {
def method[A,B](b:B)(implicit blah:Blah[A,B]):List[A] = {
blah(b)
}
method(List(2,3))
}
If I remove the method Blah.blah2
, the compiler fails because it can't resolve an implicit. Why does the second form (using an implicit evidence) works instead, and when it should be used?
Upvotes: 1
Views: 59
Reputation: 13985
Well... its because it is not able to infer correct types as the first implicit blah1
expects a relation between A
and B
.
scala> :pa
// Entering paste mode (ctrl-D to finish)
trait Blah[A,B] {
def apply(b:B):List[A]
}
object Blah {
implicit def blah1[A,B<:List[A]]:Blah[A,B] = new Blah[A,B] {
def apply(b:B):List[A] = b
}
}
def method[A,B](b:B)(implicit blah:Blah[A,B]):List[A] = {
blah(b)
}
// Exiting paste mode, now interpreting.
defined trait Blah
defined object Blah
method: [A, B](b: B)(implicit blah: Blah[A,B])List[A]
scala> method( List( 4, 5) )
<console>:37: error: could not find implicit value for parameter blah: Blah[A,List[Int]]
method( List( 4, 5) )
^
See... its looking for implicit
of type Blah[ A, List[ Int ] ]
We just need to help it with types and it will work,
scala> method[ Int, List[ Int] ]( List( 3, 4, 5 ) )
res1: List[Int] = List(3, 4, 5)
Upvotes: 1