Now we need a type class that will allow us to take a Poly2, partially apply it to something, and map the resulting unary function over an HList:trait ApplyMapper[HF, A, X <: HList, Out <: HList] { def apply(a: A, x: X): Out}object ApplyMapper { implicit def hnil[HF, A] = new ApplyMapper[HF, A, HNil, HNil] { def apply(a: A, x: HNil) = HNil } implicit def hlist[HF, A, XH, XT <: HList, OutH, OutT <: HList](implicit pb: Poly.Pullback2Aux[HF, A, XH, OutH], am: ApplyMapper[HF, A, XT, OutT] ) = new ApplyMapper[HF, A, XH :: XT, OutH :: OutT] { def apply(a: A, x: XH :: XT) = pb(a, x.head) :: am(a, x.tail) }}现在有一个类型类来帮助提升:And now a type class to help with the lifting:trait LiftA2[HF, X <: HList, Y <: HList, Out <: HList] { def apply(x: X, y: Y): Out}object LiftA2 { implicit def hnil[HF, Y <: HList] = new LiftA2[HF, HNil, Y, HNil] { def apply(x: HNil, y: Y) = HNil } implicit def hlist[ HF, XH, XT <: HList, Y <: HList, Out1 <: HList, Out2 <: HList, Out <: HList ](implicit am: ApplyMapper[HF, XH, Y, Out1], lift: LiftA2[HF, XT, Y, Out2], prepend : PrependAux[Out1, Out2, Out] ) = new LiftA2[HF, XH :: XT, Y, Out] { def apply(x: XH :: XT, y: Y) = prepend(am(x.head, y), lift(x.tail, y)) }}最后是我们的方法本身:And finally our method itself:def liftA2[HF, X <: HList, Y <: HList, Out <: HList](hf: HF)(x: X, y: Y)(implicit lift: LiftA2[HF, X, Y, Out]) = lift(x, y)这就是全部——现在 liftA2(tuple)(xs, ys) 起作用了.And that's all—now liftA2(tuple)(xs, ys) works.scala> type Result = | (Int, Double) :: (Int, String) :: | (Symbol, Double) :: (Symbol, String) :: | (Char, Double) :: (Char, String) :: HNildefined type alias Resultscala> val res: Result = liftA2(tuple)(xs, ys)res: Result = (1,4.0) :: (1,e) :: ('b,4.0) :: ('b,e) :: (c,4.0) :: (c,e) :: HNil正如我们所愿. 这篇关于从两个 HList 创建所有对的 HList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-12 08:25