Passing a Shapeless Extensible Record to a Function (continued)

前端 未结 2 1180
梦谈多话
梦谈多话 2020-12-09 12:51

Considering this question : Passing a Shapeless Extensible Record to a Function, Travis\'s answer shows that every function taking an extensible record as parameter must hav

2条回答
  •  余生分开走
    2020-12-09 13:26

    You can define your own type class to gather the evidence that the record has the fields you need:

    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]
    }
    

    And then, for example:

    def fun1[L <: HList](xs: L)(implicit selectors: HasMyFields[L]) = {
      import selectors._
    
      (xs("foo1"), xs("foo2"), xs("foo3"))
    }
    

    It's still a little verbose, especially since the import is necessary, but much less so than requiring all of the selectors individually as implicit parameters.

提交回复
热议问题