从 HList 获取元素
Getting elements from an HList
我玩弄了 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
return 一个 Int
和 String
根据它的参数。我想,如果可能的话,我必须使用 Aux
或 at
但我不确定该怎么做。
沿着这些方向尝试一些东西,
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
类型 class 实例,该实例用于在 get
.
中执行索引
另请注意,因为存在从 Int
文字到 Nat
的隐式转换,您可以编写
scala> container.get(0)
res3: Int = 1
scala> container.get(1)
res4: String = foo
我玩弄了 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
return 一个 Int
和 String
根据它的参数。我想,如果可能的话,我必须使用 Aux
或 at
但我不确定该怎么做。
沿着这些方向尝试一些东西,
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
类型 class 实例,该实例用于在 get
.
另请注意,因为存在从 Int
文字到 Nat
的隐式转换,您可以编写
scala> container.get(0)
res3: Int = 1
scala> container.get(1)
res4: String = foo