Reputation: 1706
Let's say I define some type in a trait, that should implement some type class (like functor):
import cats.Functor
import cats.syntax.functor.toFunctorOps
trait Library {
type T[+A]
implicit val isFunctor: Functor[T]
}
Now, I want to use this library. The following works fine:
trait LibraryUser {
val l: Library
import l._
def use: T[Boolean] = {
val t: T[Int] = ???
t.map(_ => true)
}
}
But when using it in a method with a parameter instead, the import of the implicit isn't working (out commented line doesn't compile) and you have to write the implicit for yourself instead:
object LibraryUser1 {
def use(l: Library): l.T[Boolean] = {
import l._
val t: T[Int] = ???
//t.map(_ => true)
toFunctorOps(t)(isFunctor).map(_ => true)
}
}
Why is this the case / what can be done against it.
Upvotes: 2
Views: 64
Reputation: 55569
This has previously been filed as a bug, specifically SI-9625. Implicits values that are path-dependent and return higher-kinded types fail to resolve. Here is a simplified example using the standard library:
trait TC[F[_]]
trait Foo {
type T[A]
implicit val ta: TC[T]
}
object Bar {
def use(foo: Foo) = {
import foo._
implicitly[TC[T]] // fails to resolve, but `implicitly[TC[T]](ta)` is fine
}
}
Sadly, even the most obvious use of the implicit fails:
object Bar {
def use(foo: Foo) = {
implicit val ta: TC[foo.T] = null
implicitly[TC[foo.T]] // nope!
}
}
Upvotes: 1