Scala 不会为无形 HList 派生依赖类型(使用 Aux)

Scala doesn't derive dependent type for shapeless HList (using Aux)

给定类型相关的转换器类型 class,它可以将字符串转换为整数:

trait Converter[From] {
  type To
  def to(from: From): To
}

object Converter {
  type Aux[From, Out0] = Converter[From] { type To = Out0 }

  implicit val forInteger = new Converter[Integer] {
    type To = String
    def to(value: Integer) = ???
  }
}

// this works
val single = the[Converter[Integer]]
implicitly[single.To =:= String]
val singleAux = the[Converter.Aux[Integer, String]]

我希望它适用于 HList,例如Integer :: HNil。理论上,我需要的只是 HNil 和 HList 的隐式:

implicit val forHNil = new Converter[HNil] {
  type To = HNil
  def to(value: HNil) = HNil
}

implicit def forHList[Head, HeadConverted, Tail <: HList, TailConverted <: HList](
  implicit
  hConverter: Converter.Aux[Head, HeadConverted],
  tConverter: Converter.Aux[Tail, TailConverted]
  ): Converter[Head :: Tail] = new Converter[Head :: Tail] {
    type To = HeadConverted :: TailConvertedHList
    def to(values: Head :: Tail) = ???
  }

以上适用于 HNil:

val hnil = the[Converter[HNil]]
implicitly[hnil.To =:= HNil]
val hnilAux = the[Converter.Aux[HNil, HNil]]

但不适用于 HList。有趣的是,它确实找到了一个实例,但并没有导出结果类型

val hlist = the[Converter[Integer :: HNil]]
type expected = String :: HNil
implicitly[hlist.To =:= expected] //fails
val hlistAux = the[Converter.Aux[Integer :: HNil, String :: HNil]] // fails

我已经在一个独立的项目中设置了它,该项目有更多(失败的)尝试来调试问题:https://github.com/mpollmeier/shapeless-dependent-type-typeclass-problem

问题是我把forHList的return类型明确声明为Converter[Head :: Tail]。 return 类型不完整,缺少我需要的部分。

只需将声明的 return 类型更改为 Converter.Aux[Head :: Tail, HeadConverted :: TailConverted](或者甚至只是将其保留)即可解决问题。

这个答案的所有功劳都归功于 Miles Sabin,他在上面的评论中提到了这个问题。谢谢!