给定一个类型相关的Converter类型,它可以将String转换为整数:
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) = ???
}
上述情况适用于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
答案 0 :(得分:1)
问题在于我明确将forHList
的返回类型称为Converter[Head :: Tail]
。返回类型不完整,并且它完全缺少我需要的部分。
只需将声明的返回类型更改为Converter.Aux[Head :: Tail, HeadConverted :: TailConverted]
(甚至只是将其删除)即可解决问题。
这个答案都归功于Miles Sabin,他在上面的评论中提到了这个问题。谢谢!