给出Sized
列表。如果它存在,怎么可以选择修改头?
也就是说,如何定义ff:
def addOneToHeadIfExists[N <: Nat](l: Sized[IndexedSeq[Int], N]): Sized[IndexedSeq[Int], N] = ???
也就是说,我可以打电话:
val x: Sized[IndexedSeq[Int], _3] = Sized(1, 2, 3)
addOneToHeadIfExists(x) // gives Sized(2, 2, 3)
val y: Sized[IndexedSeq[Int], _0] = Sized() // sample. doesn't actually compile
addOneToHeadIfExists(x) // gives Sized()
答案 0 :(得分:1)
无形大小类型的主要目的是在编译时提供有关值的足够信息,以便不需要对此类属性进行运行时测试。
验证大小的集合是非空的,因此head
和tail
定义明确是非常简单的,并且是无形的情况之一,其中隐式证据不是立即的必要。这是因为我们可以通过在length类型参数中要求至少一个外部Succ
类型构造函数来捕获序列大小大于0的约束。
这给了我们,
def addOneToHead[N <: Nat](l: Sized[IndexedSeq[Int], Succ[N]]):
Sized[IndexedSeq[Int], Succ[N]] = (l.head+1) +: l.tail
此方法是针对所有Succ[N]
的长度为N
的大小序列定义的,其中N
为Nat
,即所有大于0的nat。
示例REPL会话,
scala> addOneToHead(Sized(1, 2, 3))
res0: shapeless.Sized[IndexedSeq[Int],shapeless.Succ[shapeless.nat._2]] =
Vector(2, 2, 3)
scala> addOneToHead(Sized())
<console>:16: error: polymorphic expression cannot be instantiated to expected type
found : [CC[_]]shapeless.Sized[CC[Nothing],shapeless._0]
required: shapeless.Sized[IndexedSeq[Int],shapeless.Succ[?]]
addOneToHead(Sized())
^
正如您所看到的,这是一个类型错误,因为对于任何nat类型_0
,编译器无法将类型Succ[N]
与N
统一起来。