从 HList 中获取元素

8

我尝试过使用HList,以下内容按预期工作:

val hl = 1 :: "foo" :: HNil
val i: Int = hl(_0)
val s: String = hl(_1)

然而,我无法让下面的代码正常工作(暂且假设对列表进行随机访问是一个聪明的想法;-)):

class Container(hl: HList) {
    def get(n: Nat) = hl(n)
}

val container = new Container(1 :: "foo" :: HNil)
val i: Int = container.get(_0)
val s: String = container.get(_1)

我希望 get 能够根据它的参数返回一个整数和一个字符串。我认为,如果可能的话,我需要使用 Auxat,但我不确定如何实现这一点。
1个回答

5

尝试按照以下方式进行:

scala> import shapeless._, nat._, ops.hlist._
import shapeless._
import nat._
import ops.hlist._

scala> class Container[L <: HList](hl: L) {
     |   def get(n: Nat)(implicit at: At[L, n.N]): at.Out = hl[n.N]
     | }
defined class Container

scala> val container = new Container(1 :: "foo" :: HNil)
container: Container[shapeless.::[Int,shapeless.::[String,shapeless.HNil]]] = ...

scala> container.get(_0)
res1: Int = 1

scala> container.get(_1)
res2: String = foo

这里的第一个关键区别是,我们不再将 hl 作为普通的 HList 进行输入,而是对参数的确切类型进行参数化,并保留其结构为 L。第二个区别是,我们使用 L 来索引隐式的 At 类型类实例,这用于在 get 中执行索引操作。
还要注意的是,由于从 Int 字面量到 Nat 的隐式转换,您可以编写以下代码:
scala> container.get(0)
res3: Int = 1

scala> container.get(1)
res4: String = foo

1
太好了!感谢你的库! - user3127060

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接