微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

shapeless Record 类型可以用作 Poly1 吗?

如何解决shapeless Record 类型可以用作 Poly1 吗?

假设我有以下记录类型的数据和一个键列表:

    val rr = ("a" ->> 1) ::
      ("b" -> "s") ::
      ("c" -> 3) ::
      HNil

val hh = "c" :: "b" :: HNil

我想为 rr 中的每个键提取 hh 中的值,然后将它们组合成一个类型级别的对象,最终产生:

(3: Int) :: ("s": String) :: HNil

如何用最少的代码实现这一点?我显然可以写一个归纳召唤的隐式函数,但它似乎有点矫枉过正

解决方法

首先,你有错别字。 -> 应该代替 val hh = "c" :: "b" :: HNil

其次,"c" :: "b" :: HNil 没有 String :: String :: HNil 类型,而是 hh 类型(因此您丢失了有关键的编译时信息)。如果您希望 "c" :: "b" :: HNil 具有 rr 类型(以便可以从 .narrow 中提取具有此类键的值),那么您应该使用 type hht = "c" :: "b" :: HNil val hh: hht = "c".narrow :: "b".narrow :: HNil

shapeless.ops.record.Selector

第三,如果你想通过一个键从记录中提取一个值,你应该使用类型类 shapeless.ops.record.SelectAll。如果您想通过多个键提取多个值,您应该使用类型类 getapply 中通过 Selector 定义了扩展方法 shapeless.record._/SelectAll 但我找不到通过 get 定义的方法,因此您可以类似地自己定义它到apply/implicit class RecordOps[L <: HList](val l : L) { def getAll[K <: HList](k: K)(implicit selector: SelectAll[L,K]): selector.Out = selector(l) def getAllByType[K <: HList](implicit selector: SelectAll[L,K]): selector.Out = selector(l) } rr.getAll(hh) // 3 :: s :: HNil rr.getAllByType[hht] // 3 :: s :: HNil

{{1}}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。