使用从一个函数返回的 Shapeless Nat 作为另一个函数的参数

Using a Shapeless Nat returned from a function as a parameter for another function

我有以下函数,它采用形状为 Point(d0, d1,...,dK) 和 returns 的 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,以及 returns 位于 [=26= 表示的维度的元素]自然:

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

您应该修改 findMaxRangeDim,使其 returns 特定于 N <: Nat(例如,将其添加为类型参数),而不只是 Nat(太粗糙了)。

现在 getAt(data.head, findMaxRangeDim(data)) 不起作用,因为没有 At.Aux[H, Nat, BigDecimal](但是对于特定的 N <: NatAt.Aux[H, N, BigDecimal])。

隐式在编译时解析,而不是在运行时解析。

我尝试了 的方法,但编译器只会抱怨它找不到正确类型的隐式。

然后在Shapeless的gitter频道问了一下,才知道编译器需要在编译时知道Nat的具体类型。因为我的代码在 运行时 找到了正确的 Nat,编译器无法事先知道要使用哪种类型。

经验教训是,Nats 与典型 Iterables 中的索引不同。