如何使函数采用 HList 的反转

how to make function taking reverse of an HList

我有这样的示例代码

implicit def func[T <: HList, F, R](
  implicit fp: FnToProduct.Aux[F, Reverse[T]#Out => R], 
  rev: Reverse[T]): (F, T) => R = 
  (f: F, t: T) => f.toProduct(t.reverse)

所以我想要的是要求编译器隐式解析一个函数F,将HList的反转作为其输入和输出R。例如,

type R = java.util.Date
type F2 = Function2[String, Int, R]
type TT = Int :: String :: HNil

implicitly[(F2, TT) => R]

虽然 implicit func 可以编译,但上面的示例代码无法解析我认为它应该能够找到的隐式。有什么问题吗?

类型投影在 Shapeless 中很少有用,因为编译器静态地不太了解例如Reverse[T]#Out。如果你能在它的位置写 rev.Out 就好了,但你不能(那是 a long story…)。相反,您需要添加一个类型参数来表示反转的 HList:

import shapeless._, ops.function.FnToProduct, ops.hlist.Reverse

implicit def func[T <: HList, TR <: HList, F, R](implicit
  fp: FnToProduct.Aux[F, TR => R],
  rev: Reverse.Aux[T, TR]
): (F, T) => R = (f: F, t: T) => fp(f)(rev(t))

这将按预期工作,但我建议不要将这样的函数放入隐式范围。