gpt4 book ai didi

scala - 将 HList 转换为列表列表

转载 作者:行者123 更新时间:2023-12-05 01:03:35 25 4
gpt4 key购买 nike

如何将 HList 转换为 HList 的 HList,如下面的代码片段所示。

import shapeless._
import Nat._

case class A(i: Int)
case class B(str: String)
case class C(i: Int, str: String)

type Input = A :: B :: C :: HNil
val in: Input = A(1) :: B("b") :: C(2, "c") :: HNil

type X = A :: HNil
val x: X = A(1) :: HNil

type Y = A :: B :: HNil // could also be B :: HNil
val y: Y = A(1) :: B("b") :: HNil

type Z = A :: C :: HNil // could also be B :: C :: HNil
val z: Z = A(1) :: C(2, "c") :: HNil

type Output = X :: Y :: Z :: HNil
val out: Output = x :: y :: z :: HNil

// Illustrates what I want to accomplish.
def build(in: Input) : Output = {
val x: X = in(_0) :: HNil
val y: Y = in(_0) :: in(_1) :: HNil
val z: Z = in(_0) :: in(_2) :: HNil
x :: y :: z :: HNil
}

println(build(in) == out) // true


def magic[In <: HList, Out <: HList](in: In) : Out = ???
println(magic[Input, Output](in) == out)

我要建 Output给定 Input通过 magic以某种方式映射输入并最终得到什么的方法 build输出。

最佳答案

对于自定义类型类,这还不错。请注意,从某种意义上说,我们需要两个“基本案例”——一个用于启动顶级 HList , 和一个开始每个单独的内部 HList .然后,归纳步骤展示了如何向最后一个 HList 添加一个新项目(我们知道如何从输入中提取)。我们已经添加了。

import shapeless._, ops.hlist.Selector

trait Picker[I <: HList, O <: HList] {
def apply(i: I): O
}

object Picker {
implicit def hnilPicker[I <: HList]: Picker[I, HNil] = new Picker[I, HNil] {
def apply(i: I) = HNil
}

implicit def hnilHlistPicker[I <: HList, OT <: HList](implicit
picker: Picker[I, OT]
): Picker[I, HNil :: OT] = new Picker[I, HNil :: OT] {
def apply(i: I) = HNil :: picker(i)
}

implicit def hlistPicker[I <: HList, OHH, OHT <: HList, OT <: HList](implicit
sel: Selector[I, OHH],
picker: Picker[I, OHT :: OT]
): Picker[I, (OHH :: OHT) :: OT] = new Picker[I, (OHH :: OHT) :: OT] {
def apply(i: I) = picker(i) match {
case h :: t => (sel(i) :: h) :: t
}
}
}

进而:
def magic[In <: HList, Out <: HList](in: In)(implicit
picker: Picker[In, Out]
): Out = picker(in)

最后:
scala> println(magic[Input, Output](in))
A(1) :: HNil :: A(1) :: B(b) :: HNil :: A(1) :: C(2,c) :: HNil :: HNil

scala> println(magic[Input, Output](in) == out)
true

能够仅指定输出类型并推断输入类型会很好,但遗憾的是没有方便的方法来实现它。

关于scala - 将 HList 转换为列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24537035/

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