在无形状中,我正在尝试编写一个函数,使得任意长度的两个HList l1
和l2
具有以下属性:
l1
和l2
的长度相同。l2
包含l1
的确切类型,包含在常量外部类型构造函数中。所以,如果l1
是
1 :: 1.2 :: "hello" :: HNil`
l2
可能是
Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil
使用UnaryTCConstraint
和LengthAux
可以限制长度,并且需要l2
的静态外部构造函数,但是如果它们符合,则会成为问题。
关于如何实现它的任何想法?
答案 0 :(得分:9)
Mapped
正好提供了这种约束,而无需Length
。来自the documentation:
键入类,见证包装每个元素的结果 类型构造函数
HList
中的L
F
为Out
。
以下是它在1.2.4中的表现:
import shapeless._
def foo[L1 <: HList, L2 <: HList](l1: L1, l2: L2)(implicit
ev: MappedAux[L1, Ordering, L2]
) = ()
val l1 = 1 :: 1.2 :: "hello" :: HNil
val l2 = Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil
val l3 = Ordering[Int] :: Ordering[Double] :: Ordering[Char] :: HNil
然后:
scala> foo(l1, l2)
scala> foo(l1, l3)
<console>:17: error: could not find implicit value for parameter ev: ...
正如所料。对于2.0,只需添加shapeless.ops.hlist._
导入,然后将MappedAux
替换为Mapped.Aux
,即可开始使用。