我有以下函数,该函数获取形状为 Point(d0,d1,...,dK)的K维点的列表,并返回该范围的维的索引最大。索引返回为 Nat :
def findMaxRangeDim[T, H <: HList, L <: HList, K<: HList](data: List[T])(
implicit gen: Generic.Aux[T, H],
zipper: Zip.Aux[H::H::HNil, L],
maxMapper: Mapper.Aux[mergeMaxMap.type, L, H],
minMapper: Mapper.Aux[mergeMinMap.type, L, H],
diffMapper: Mapper.Aux[absDiffMap.type, L, H],
indexZipper: ZipWithIndex.Aux[H, K],
folder: LeftFolder.Aux[K, (BigDecimal, Nat), maxIndexFinder.type,
(BigDecimal, Nat)]
): Nat = {/*implementation*/}
假设我有另一个函数,该函数需要一个数据点和一个 Nat ,并返回位于由 Nat 表示的尺寸处的元素:
def getAt[T, H<:HList, N<:Nat](p: T, n: N)(
implicit gen: Generic.Aux[T, H],
at: At.Aux[H, N, BigDecimal]
) = {/*implementation*/}
在可以确认:
// This compiles:
getAt(data.head, Nat._1)
// This doesn't:
getAt(data.head, findMaxRangeDim(data))
错误是could not find implicit value for parameter at: shapeless.ops.hlist.At.Aux[H,shapeless.Nat,BigDecimal]
。
我猜想这是因为shapeless正在寻找findMaxRangeDim(data)
结果的确切类型的隐式,但这仅在运行时才知道。有什么方法可以隐式传递权限,并在另一个函数中使用结果 Nat ?
答案 0 :(得分:0)
您应该修改findMaxRangeDim
,使其返回特定的N <: Nat
(例如,将其添加为类型参数),而不是仅仅返回Nat
(太粗糙了)。
现在getAt(data.head, findMaxRangeDim(data))
不起作用,因为没有At.Aux[H, Nat, BigDecimal]
(但是特定的At.Aux[H, N, BigDecimal]
有N <: Nat
)。
隐式在编译时解决,而不是在运行时解决。
答案 1 :(得分:0)
我通过Dmytro Mitin尝试了该方法,但是编译器只会抱怨找不到正确类型的隐式。
然后我在Shapeless的gitter频道中询问,意识到编译器需要在编译时知道Nat
的特定类型。因为我的代码在运行时处找到了正确的Nat
,所以编译器无法事先知道要使用哪种类型。
吸取的教训是Nat
与典型的Iterables中的索引并不相似。