【问题标题】:Shapeless HList fill based on length of type基于类型长度的无形 HList 填充
【发布时间】:2019-10-18 09:35:10
【问题描述】:

使用HLists 的选项,我试图生成一个所有元素都等于None 的HList。但是Fill对象的隐式解析存在问题。

natLength 函数源于这个 SO 答案:The length of HList type paremeter in terms of Nat。

type OL = Option[Double] :: Option[Int] :: Option[String] :: HNil


def emptyList[T <: HList: *->*[Option]#λ](length: Nat)(
  implicit fill: Fill.Aux[length.N, None.type, T]
): T = {
  HList.fill(length)(None)
}

def natLength[T <: HList](implicit length: Length[T]): length.Out = length()

emptyList[OL](natLength[OL])

上面的代码让编译器因为这个错误而失败:

could not find implicit value for parameter fill: 
shapeless.ops.hlist.Fill[shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]],None.type]{type Out = Option[Double] :: Option[Int] :: Option[String] :: shapeless.HNil}

我想要实现的目标可能吗?仅根据类型的长度生成HList?

【问题讨论】:

    标签: scala implicit shapeless hlist


    【解决方案1】:

    调试隐式的标准方法是尝试手动(显式)解决它们并查看编译错误。

    emptyList[OL](natLength[OL])(
      implicitly[*->*[Option]#λ[Option[Double] :: Option[Int] :: Option[String] :: HNil]],
      implicitly[Fill.Aux[_3, None.type, None.type :: None.type :: None.type :: HNil]],
    )
    

    生产

    Error: type mismatch;
     found   : shapeless.ops.hlist.Fill[shapeless.nat._3,None.type]{type Out = None.type :: None.type :: None.type :: shapeless.HNil}
        (which expands to)  shapeless.ops.hlist.Fill[shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]],None.type]{type Out = None.type :: None.type :: None.type :: shapeless.HNil}
     required: shapeless.ops.hlist.Fill[shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]],None.type]{type Out = Option[Double] :: Option[Int] :: Option[String] :: shapeless.HNil}
        implicitly[Fill.Aux[_3, None.type, None.type :: None.type :: None.type :: HNil]],
    

    def emptyList[T &lt;: HList: *-&gt;*[Option]#λ]... 中的 T 应该是什么?是Option[Double] :: Option[Int] :: Option[String] :: HNil吗?那你为什么要求隐式Fill.Aux[length.N, None.type, T] 与Out-type 相同T 而它应该是None.type :: None.type :: None.type :: HNil。

    试试

    def emptyList(length: Nat)(
      implicit fill: Fill[length.N, None.type]
    ): fill.Out = {
      HList.fill(length)(None)
    }
    
    emptyList(natLength[OL]) //None :: None :: None :: HNil
    

    *-&gt;*[Option]#λ 可以在def natLength 中绑定上下文。

    【讨论】:

    • 谢谢,如果我用具体类型调用emptyList,效果会很好。但是,当我从本身具有类型参数 T &lt;: HList 的方法调用 emptyList[T] 时,它不起作用。
    • @Yann emptyList[T] 是什么?在我的回答中没有emptyList[T]。在我的回答中是def emptyList(length: Nat)... 写你的代码。
    猜你喜欢
    • 2014-06-03
    • 2021-02-18
    • 1970-01-01
    • 2017-02-10
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    相关资源
    最近更新 更多