代码之家  ›  专栏  ›  技术社区  ›  Adrian

从hlist中检索元素的函数(同时保留其类型)

  •  0
  • Adrian  · 技术社区  · 7 年前

    我有这种类型,将通过无形状生成:

    type hlistt = STUDENT.type :: AUTO_LOANS.type :: HNil
    

    基本上,我有很多case对象扩展了一个特性,所以我设法创建了一个方法,它将所有case对象的实例作为hlist提供给我。

    然后使用 import shapeless.ops.hlist.Last init 如果值等于字符串“student”,我编写了一个方法来检索hlist中的一个节点:

    def getLast(hl:hlistt) = {
      val last0=Last[hlistt]
      val la=last0(hl)
    
      if (la.value == "student") la
      else init(hl)
    }
    

    问题是,如果调用此方法,将无法从HLIST中获得正确的节点类型。

    getLast(STUDENT :: AUTO_LOANS :: HNil)
    

    该方法工作并返回节点,但类型为“关”:

    Product with Serializable = STUDENT :: HNil
    

    我需要一些证人/aux隐式返回正确的类型吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Dmytro Mitin    7 年前

    la 属于类型 AUTO_LOANS.type , init(hl) 属于类型 STUDENT.type :: HNil ,所以

    if (la.value == "student") la
    else init(hl)
    

    属于类型 Any (或) Product with Serializable )

    如果要从不同的分支返回不同类型的值,则需要 Poly .

    import shapeless.{Poly1, Witness}
    
    object myPoly extends Poly1 {
      implicit def studentCase: Case.Aux[Witness.`"student"`.T, STUDENT.type] = 
        at(_ => STUDENT)
      implicit def autoLoansCase: Case.Aux[Witness.`"auto-loans"`.T, AUTO_LOANS.type] = 
        at(_ => AUTO_LOANS)
    }
    
    import shapeless.syntax.singleton._
    println(
      myPoly("student".narrow)
    ) // STUDENT
    
    println(
      myPoly("auto-loans".narrow)
    ) // AUTO_LOANS
    
    // println(
    //   myPoly("abc".narrow)
    // )  // doesn't compile
    

    如果字符串在编译时已知,则此方法有效。

        2
  •  1
  •   Dominic Egger    7 年前

    我不太确定你想做什么。鉴于:

    type hlistt = STUDENT.type :: AUTO_LOANS.type :: HNil
    

    Last[hlistt] 将决心 AUTO_LOANS.type (你的真中频分支) 虽然 init 将决心 STUDENT :: HNil (你的假发分支)

    这些类型的lub(最小上界)将是 Product with Serializable 所以这就是你看到的原因。

    如果要检查hlist成员的运行时属性,则必须使用适当的机制派生相应的类型边界和结果类型,从而使它们通过线程。在这种情况下,它已经由shapeless给出。

    https://scalafiddle.io/sf/fdtn3cz/0

    这就是你想要的吗?

    编辑: 我也刚读过

    我有这种类型,将动态生成:

    你所说的“动态”到底是什么意思?因为除非您可以指定一些编译时属性,否则shapeless可能不是您要寻找的解决方案。

    推荐文章