Defining instances of a third-party typeclass, implicit not found but explicit works fine
我正在使用Slick的
的实例
我想要的是:
给出一个隐式的
隐式生成
我尝试了什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | trait CanGetOption[T] { def getOption: GetResult[Option[T]] } object CanGetOption { // convenience implicit resolver def apply[T](implicit canGetOption: CanGetOption[T]): CanGetOption[T] = canGetOption // base case: HNil implicit val getHNilOption: CanGetOption[HNil] = from(GetResult { _ => Some(HNil) }) // recursion case: H :: Tail implicit def getHConsOption[H, Tail <: HList]( implicit getHeadOption: GetResult[Option[H]], canGetTailOption: CanGetOption[Tail] ): CanGetOption[H :: Tail] = from(GetResult[Option[H :: Tail]] { r => val headOpt = getHeadOption(r) val tailOpt = canGetTailOption.getOption(r) for(head <- headOpt; tail <- tailOpt) yield head :: tail }) // generic case: A, given a A <-> Repr conversion // I also tried moving this into a"LowPriorityImplicits" thing, just in case implicit def getGenericOption[A, Repr <: HList]( implicit gen: Generic.Aux[A, Repr], getReprOpt: CanGetOption[Repr] ): CanGetOption[A] = from(GetResult { r => val reprOpt = getReprOpt.getOption(r) reprOpt.map(gen.from) }) } implicit def resolveOptionGetter[T: CanGetOption]: GetResult[Option[T]] = CanGetOption[T].getOption |
问题:
当我导入上面的内容时,在搜索隐式对象时似乎没有考虑
1 2 3 4 5 6 7 | scala> implicitly[GetResult[Option[(Int, Int)]]] <console>:19: error: could not find implicit value for parameter e: scala.slick.jdbc.GetResult[Option[(Int, Int)]] implicitly[GetResult[Option[(Int, Int)]]] ^ scala> resolveOptionGetter[(Int, Int)] res1: scala.slick.jdbc.GetResult[Option[(Int, Int)]] = <function1> |
为什么编译器在隐式搜索中找不到
问题是
一种解决方法是使用自定义不变类型别名
1 2 3 4 5 |
现在
方差通常会给隐式解析带来麻烦:
https://github.com/scala/bug/issues/10099
https://github.com/locationtech/geotrellis/issues/1292
具有协方差的隐式分辨率