未找到部分应用类型的隐式

Implicit not found for partially applied type

虽然这个问题是在使用 shapeless and kind-projector 的代码中发现的,但没有它们也可以重现此行为。

假设我有简单类型class 用于具体化类型class 不完整实现的实例(LiftAll 的镜像)。

sealed trait LiftAll1[F[_], In] {
  type Out
  def instances: Out
}

object LiftAll1 {
  type Aux[F[_], In0, Out0] = LiftAll1[F, In0] {type Out = Out0}
  implicit def unit[F[_]]: Aux[F, Unit, Unit] = new LiftAll1[F, Unit] {
    type Out = Unit
    def instances = Unit
  }
}

还有一些非常简单的类型class来测试它

sealed class FirstIs[M, T]
object FirstIs {
  implicit def firstIs[M, D]: FirstIs[M, (M, D)] = new FirstIs
}

如果我尝试通过别名部分应用 FirstIs,并通过 LiftAll1

获取实例,一切正常
type FirstIsInt[D] = FirstIs[Int, D]
implicitly[LiftAll1[FirstIsInt, Unit]]

但是内联部分类型应用导致编译错误

implicitly[LiftAll1[({type lambda[x] = FirstIs[Int, x]})#lambda, Unit]]
//Error: could not find implicit value for parameter e: LiftAll1[[x]FirstIs[Int,x],Unit]

如何在这种情况下找到部分应用类型classes?

正如@Reactormonk 所建议的,编译器 was brought to its sensesbuild.sbt

中包含以下行
scalacOptions += "-Ypartial-unification"

在那段原始代码之后,接近

import shapeless._, ops.hlist._

LiftAll[FirstIs[Int, ?], HNil]

编译成功

AFAIK 问题是 scala 编译器无法将 FirstIs[Int,_] 理解为 F[_]in supplied implicit def without direct type alias 。幸运的是,这在最新的 Scala 实现中得到了修复。