从 HList 中获取元素 [英] Getting elements from an HList
问题描述
我玩弄了 HList 并按预期工作:
I toyed around with HList and the following works as expected:
val hl = 1 :: "foo" :: HNil
val i: Int = hl(_0)
val s: String = hl(_1)
但是,我无法让以下代码工作(让我们暂时假设随机访问列表是一个聪明的主意;-)):
However, I can't get the following piece of code working (let's assume for a moment random access on lists is a smart idea ;-)):
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
根据它的参数返回一个 Int
和 String
.我假设,如果可能的话,我必须使用 Aux
或 at
但我不知道如何做到这一点.
I'd like to have get
return an Int
and String
according to it's parameter. I assume, if possible at all, I have to use Aux
or at
but I'm not sure how to do this.
推荐答案
尝试这些方法,
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
中执行索引.
The first crucial difference here is that rather than typing hl
as plain HList
, which loses all specific information about the types of the elements, we parametrize over the precise type of the argument and preserve its structure as L
. The second difference is that we use L
to index the implicit At
type class instance which is used to perform the indexing in get
.
另请注意,由于存在从 Int
文字到 Nat
的隐式转换,您可以编写,
Also note that because there is an implicit conversion from Int
literals to Nat
's you can write,
scala> container.get(0)
res3: Int = 1
scala> container.get(1)
res4: String = foo
这篇关于从 HList 中获取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!