[英]How to zip values with types? Shapeless
我有一个看起来像这样的副产品的HList
:
(A :+: B :+: CNil) :: (Foo :+: Bar :+: CNil) :: HNil
这个HList
将是我程序中的一个值。 例如,:
val myhlist: (A :+: B :+: CNil) :: (Foo :+: Bar :+: CNil) :: HNil = ???
我有另一个 HList 的副产品,看起来像这样:
(A :+: CNil) :: (Bar :+: CNil) :: HNil
但是,这个HList在整个程序中都不会是一个值; 它仅存在于类型级别。
我想 zip 这两个 HLists 与这个压缩 function:
def zipFn[A <: Coproduct, B <: Coproduct](a: A)(implicit basis: Basis[A, B]) = {
a.deembed[B]
}
A
是来自前一个 HList 的元素(在整个程序中都会有值), B
是来自后一个 HList 的元素。 我想要 zip 个值( A
)和类型( B
)。
可能是一个非常简单的问题,但不知何故我对此感到困扰?
任何指针?
--
我目前的想法是在 Shapeless 中使用咖喱化的多态 function; 就像是:
object myZipFn extends Poly1 {
implicit def default[A <: Coproduct, B <: Coproduct](implicit basis: Basis[A, B]) = at[A] { a => a.deembed[B] }
}
val curried = Poly.curried(myZipFn)
但没有多大意义,因为default
同时要求 A 和 B。
我的想法是首先一般地接受B
(没有值的类型),然后返回一个新的 function 要求A
作为值,然后我们两者都有。
谢谢
.zipWith
接受Poly2
,而不是Poly1
。 所以myZipFn
应该是
object myZipFn extends Poly2 {
implicit def default[A <: Coproduct, B <: Coproduct](implicit
basis: Basis[A, B]
): Case.Aux[A, B, basis.Out] = at[A, B] { (a, _) => a.deembed[B] }
}
在.zipWith
的不必要的第二个参数(因为你只有类型级别的第二个 HList,而不是值级别)你可以替换空值的 HList(但输入正确)
val myhlist: (A :+: B :+: CNil) :: (Foo :+: Bar :+: CNil) :: HNil = ???
type hlist1 = (A :+: CNil) :: (Bar :+: CNil) :: HNil
object nullPoly extends Poly0 {
implicit def default[A]: Case0[A] = at(null.asInstanceOf[A])
}
val nullHlist: hlist1 = FillWith[nullPoly.type, hlist1].apply()
myhlist.zipWith(nullHlist)(myZipFn)
或者,如果您不希望 HList 为空值,则必须为值/类型级别的第一个参数和类型级别的第二个参数定义自定义Zip
/ ZipWith
类型 class。
FillWith
/ nullPoly
技巧的其他用例:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.