对于部分应用类型找不到隐式



虽然此问题是使用无形和亲切项目捕获的,但可以在没有它们的情况下重现此行为。

假设我有简单的类型类型用于用不完整的实现( LiftAll的镜像)来重新化Typeclass实例。

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
  }
}

和一些非常简单的类型类测试

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]

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

如@reactormonk所建议的,编译器在build.sbt

中的以下行进行了感知
scalacOptions += "-Ypartial-unification"

之后,原始的代码接近

import shapeless._, ops.hlist._
LiftAll[FirstIs[Int, ?], HNil]

成功地编译了

afaik问题是Scala编译器无法将FirstIs[Int,_]理解为F[_]的CC_6,而无需直接类型别名。幸运的是,这是在最新的Scala实现中修复的。

相关内容

最新更新