Scala没有';t为无形状HList派生依赖类型(使用Aux)

Scala没有';t为无形状HList派生依赖类型(使用Aux),scala,types,shapeless,derived,hlist,Scala,Types,Shapeless,Derived,Hlist,给定可将字符串转换为整数的类型相关转换器类型类: 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 t

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

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]]
我希望它适用于HLists,例如
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) = ???
  }
但对一个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

我已经在一个独立的项目中设置了它,该项目还有一些(失败的)调试问题的尝试:

问题是我明确地将
forHList的返回类型声明为
转换器[Head::Tail]
。返回类型不完整,并且缺少我需要的部分

只需将声明的返回类型更改为
Converter.Aux[Head::Tail,HeadConverted::TailConverted]
(或者干脆不使用它)就可以解决问题


这个答案的所有功劳都归于迈尔斯·萨宾,他在上述评论中提到了这个问题。谢谢大家!

当然,在失败的情况下,预期的类型是
String::HNil
?另外,
IsHList
看起来是多余的。。。放一个
Ha,通过显式声明(不完整的)返回类型,我让编译器忘记了类型-非常感谢!预期的类型实际上应该是String::HNil。IsHList显然已经过时了,我只是针对它的Aux类型介绍了它,希望它能帮助编译器找到正确的类型。然而,这无论如何都不起作用。我已经更新了这个问题,并将根据您的评论发布一个答案,以便下一个人可以更轻松地解析这个问题。希望将来使用多个隐式块()时这会变得更容易。
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