【问题标题】:Dynamically create extensible record in shapeless 2.0在 shapeless 2.0 中动态创建可扩展记录
【发布时间】:2014-08-13 21:05:39
【问题描述】:

我需要生成一个可扩展的记录,给定一个 HList 的键和一个值映射,这是我想要实现的 MWE(您可以将它复制/粘贴到任何具有无形 2.0 的 REPL 中,在为了重现问题)

import shapeless._; import syntax.singleton._; import record._

case class Foo[T](column: Symbol)

val cols = Foo[String]('column1) :: HNil

val values = Map("column1" -> "value1")

object toRecord extends Poly1 {
  implicit def Foo[T] = at[Foo[T]] { foo =>
    val k = foo.column.name
    val v = values.get(k)
    (k ->> v)
  }
}

val r = cols.map(toRecord)
// r: shapeless.::[Option[String] with shapeless.record.KeyTag[k.type,Option[String]] forSome { val k: String },shapeless.HNil] = Some(value1) :: HNil

val value = r("column1")
// error: No field String("column1") in record shapeless.::[Option[String] with shapeless.record.KeyTag[k.type,Option[String]] forSome { val k: String },shapeless.HNil]
   val value = r("column1")

如果我尝试手动定义记录,一切都会按预期工作

 val q = ("column1" ->> Some("value1")) :: HNil
 // q: shapeless.::[Some[String] with shapeless.record.KeyTag[String("column1"),Some[String]],shapeless.HNil] = Some(value1) :: HNil

 q("column1")
 // Some[String] = Some(value1)

显然不同的是,在一种情况下,KeyTag 具有类型

KeyTag[String("column1"), Some[String]]

和在(非工作)其他

KeyTag[k.type,Option[String]] forSome { val k: String }

我感觉问题在于字符串k 不是静态已知的,但我不知道如何解决这个问题。 一般来说,有没有办法从键列表中动态生成可扩展记录?

我担心答案是使用宏,但如果存在其他解决方案,我会很高兴。

【问题讨论】:

    标签: scala shapeless


    【解决方案1】:

    如果您可以稍微更改您的 Foo 定义以允许它跟踪列键的单例类型,这还不错(请注意,我已删除未使用的 T 类型参数):

    import shapeless._; import syntax.singleton._; import record._
    
    case class Foo[K <: Symbol](column: Witness.Aux[K])
    
    val cols = Foo('column1) :: HNil
    val values = Map("column1" -> "value1")
    
    object toRecord extends Poly1 {
      implicit def atFoo[K <: Symbol] = at[Foo[K]] { foo =>
        field[K](values.get(foo.column.value.name))
      }
    }
    
    val r = cols.map(toRecord)
    

    然后:

    scala> val value = r('column1)
    value: Option[String] = Some(value1)
    

    请注意,我已将您的字符串键 ("column1") 更改为一个符号,因为这是我们记录的内容。

    【讨论】:

    • 太棒了!我有同样的直觉,但我不知道如何跟踪单例类型。非常感谢,特拉维斯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多