shapeless Record 类型可以用作 Poly1 吗? [英] Can shapeless Record type be used as a Poly1?

查看:53
本文介绍了shapeless Record 类型可以用作 Poly1 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Assuming if I have the following Record typed data, and a hlist of keys:

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

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

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

And I want to extract values in rr for each key in hh, then combine them into a type level object, eventually yielding:

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

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

How this can be achieved with least amount of code? I could obviously write a inductively-summoned implicit function but it seems to be overkill

推荐答案

首先,你有错别字.->> 应该代替 ->.

Firstly, you have typos. ->> should be instead of ->.

其次,val hh = "c";:: b":: HNil 没有类型 "c";:: b":: HNil,它具有类型 String :: String :: HNil (因此您将丢失有关键的编译时信息).如果您希望 hh 具有类型 "c":: b":: HNil(以便可以从 rr 中提取具有此类键的值)然​​后您应该使用 .narrow

Secondly, val hh = "c" :: "b" :: HNil doesn't have type "c" :: "b" :: HNil, it has type String :: String :: HNil instead (so you're loosing compile-time information about keys). If you want hh to have type "c" :: "b" :: HNil (so that values with such keys can be extracted from rr) then you should use .narrow

type hht = "c" :: "b" :: HNil
val hh: hht = "c".narrow :: "b".narrow :: HNil

第三,如果你想通过一个键从记录中提取一个值,你应该使用类型类shapeless.ops.record.Selector.如果您想通过多个键提取多个值,您应该使用类型类 shapeless.ops.record.SelectAll.在 shapeless.record._ 中有通过 Selector 定义的扩展方法 get/apply 但我找不到通过 SelectAll 定义的那个,所以你可以像 get/apply

Thirdly, if you want to extract a value from a record by a key you should use type class shapeless.ops.record.Selector. If you want to extract several values by several keys you should use type class shapeless.ops.record.SelectAll. There is extension method get/apply defined via Selector in shapeless.record._ but I can't find the one defined via SelectAll so you can define it yourself similarly to 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

这篇关于shapeless Record 类型可以用作 Poly1 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆