【问题标题】:Getting elements from an HList从 HList 中获取元素
【发布时间】:2016-02-21 22:18:42
【问题描述】:

我玩弄了 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 根据它的参数返回一个IntString。我假设,如果可能的话,我必须使用Auxat,但我不知道该怎么做。

【问题讨论】:

    标签: scala shapeless


    【解决方案1】:

    尝试这些方法,

    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,这会丢失有关元素类型的所有特定信息,而是对参数的精确类型进行参数化并将其结构保留为@987654324 @。第二个区别是我们使用L 来索引隐式At 类型类实例,该实例用于在get 中执行索引。

    还请注意,由于存在从 Int 文字到 Nat 的隐式转换,您可以编写,

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

    【讨论】:

    • 太棒了!感谢您的图书馆!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2018-09-02
    • 2010-11-08
    相关资源
    最近更新 更多