gpt4 book ai didi

scala - 如何在 HLists 上实现 zipWithIndex

转载 作者:行者123 更新时间:2023-12-05 00:25:19 27 4
gpt4 key购买 nike

HList 上写算法, 我需要一个 zipWithIndex功能。它现在不在无形库中,所以我决定实现它。

很明显,它可以实现为

hlist.zip(indexes)

哪里 indexesHList的索引 (0..n),可能可以通过这种方式获得:
val indexes = Nat._0 until hlist.length

这里的问题是 Nat没有 until方法。我没有找到任何 WitnessHListHList.map 一起使用的索引.

我可以用什么方法来获得 HListNatNat._0 开头直到 hlist.length ?

最佳答案

将这样的内容添加到 Shapeless 可能是有意义的:

import shapeless._, ops.hlist.Prepend

trait Range[A <: Nat, B <: Nat] extends DepFn0 { type Out <: HList }

object Range {
type Aux[A <: Nat, B <: Nat, Out0 <: HList] = Range[A, B] { type Out = Out0 }

implicit def emptyRange[A <: Nat]: Aux[A, A, HNil] = new Range[A, A] {
type Out = HNil
def apply(): Out = HNil
}

implicit def slightlyBiggerRange[A <: Nat, B <: Nat, OutAB <: HList](implicit
rangeAB: Aux[A, B, OutAB],
appender: Prepend[OutAB, B :: HNil],
witnessB: Witness.Aux[B]
): Aux[A, Succ[B], appender.Out] = new Range[A, Succ[B]] {
type Out = appender.Out
def apply(): Out = appender(rangeAB(), witnessB.value :: HNil)
}
}

def range[A <: Nat, B <: Nat](implicit r: Range[A, B]): r.Out = r()

现在你可以写 zipWithIndex很干净:
import ops.hlist.{ Length, Zip }

def zipWithIndex[L <: HList, S <: Nat, R <: HList, Out <: HList](l: L)(implicit
len: Length.Aux[L, S],
range: Range.Aux[nat._0, S, R],
zipper: Zip.Aux[L :: R :: HNil, Out]
): Out = l.zip(range())

进而:
import nat._

type Expected = (Int, _0) :: (Symbol, _1) :: (String, _2) :: HNil

val xs: Expected = zipWithIndex(1 :: 'a :: "foo" :: HNil)

您也可以使用折叠或 ZippedWithIndex[L <: HList] type 类,两者都可能更简洁一些,但不太清楚由独立有用的部分组成,例如 Range .

关于scala - 如何在 HLists 上实现 zipWithIndex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24808466/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com