gpt4 book ai didi

scala - 将无形可扩展记录传递给函数(续)

转载 作者:行者123 更新时间:2023-12-04 05:18:15 26 4
gpt4 key购买 nike

考虑到这个问题:Passing a Shapeless Extensible Record to a Function,Travis的答案表明,每个以可扩展记录为参数的函数都必须有一个隐式选择器作为参数。我想知道如果我们有很多这种功能的话,是否可以分解这些声明。
例如。 :

val w1 = Witness("foo1")
val w2 = Witness("foo2")
val w3 = Witness("foo3")
//Here some "magical" declarations avoiding to declara selectors in fun1, fun2, fun3 below

def fun1[L <: HList](xs: L) = ... //Access to foo1, foo2, foo3
def fun2[L <: HList](xs: L) = ... //Access to foo1, foo2, foo3
def fun3[L <: HList](xs: L) = ... //Access to foo1, foo2, foo3

谢谢

贝诺伊特

于12月10日编辑

当尝试答案的代码时,会出现两个问题:
  • 没有告诉与foo1,foo2,foo3关联的数据的真实类型:因此,像fun1这样的函数不能使用与这些类型关联的任何方法。例如,即使foo3是Double,也不能采用其平方根。
  • 如果我使用(“foo1”->>“hello”)::(“foo2”-> 1)::(“foo3”->> 1.2):: HNiL来调用fun1,则结果为(hello,1, 1.2)具有类型(selectors.s1.Out,selectors.s2.Out,selectors.s3.Out)
    如果我尝试将1添加到最后一个值(1.2),Scala提示说它无法添加Int和selectors.s3.Out;但是,如果我这样写:
      val x = fun1(("foo1"->> "hello") :: ("foo2" -> 1)::("foo3" ->> 1.2)::HNil)

    我可以写:
      x._3 == 1.2

    和斯卡拉回答是对的!

  • 我试图以这种方式修改代码,希望类型会被传播,但是并不能解决问题。我什至无法使用(foo1->>“hello”):::(foo2-> 1)::( foo3->> 1.2):: HNil来调用fun1:
    object foo1 extends FieldOf[String]
    object foo2 extends FieldOf[Int]
    object foo3 extends FieldOf[Double]

    val w1 = Witness(foo1)
    val w2 = Witness(foo2)
    val w3 = Witness(foo3)

    case class HasMyFields[L <: HList](implicit
    s1: Selector[L, w1.T],
    s2: Selector[L, w2.T],
    s3: Selector[L, w3.T]
    )

    object HasMyFields {
    implicit def make[L <: HList](implicit
    s1: Selector[L, w1.T],
    s2: Selector[L, w2.T],
    s3: Selector[L, w3.T]
    ) = HasMyFields[L]
    }
    def fun1[L <: HList](xs: L)(implicit selectors: HasMyFields[L]) = {
    import selectors._
    (xs(foo1), xs(foo2), xs(foo3))
    }

    有进步的方法吗?

    贝诺伊特

    最佳答案

    您可以定义自己的类型类以收集证据,证明该记录具有所需的字段:

    import shapeless._, ops.record.Selector, record._, syntax.singleton._

    val w1 = Witness("foo1")
    val w2 = Witness("foo2")
    val w3 = Witness("foo3")

    case class HasMyFields[L <: HList](implicit
    s1: Selector[L, w1.T, String],
    s2: Selector[L, w2.T, Int],
    s3: Selector[L, w3.T, Double]
    )

    object HasMyFields {
    implicit def make[L <: HList](implicit
    s1: Selector[L, w1.T, String],
    s2: Selector[L, w2.T, Int],
    s3: Selector[L, w3.T, Double]
    ) = HasMyFields[L]
    }

    然后,例如:
    def fun1[L <: HList](xs: L)(implicit selectors: HasMyFields[L]) = {
    import selectors._

    (xs("foo1"), xs("foo2"), xs("foo3"))
    }

    仍然有些冗长,尤其是由于必须进行导入的情况,但比要求所有选择器分别作为隐式参数要少得多。

    关于scala - 将无形可扩展记录传递给函数(续),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20311599/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com