基于类型长度的无形 HList 填充

Shapeless HList fill based on length of type

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

natLength 函数源于这个 SO 答案:

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

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

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 <: HList: *->*[Option]#λ]... 中的 T 应该是什么?是Option[Double] :: Option[Int] :: Option[String] :: HNil吗?那你为什么要求隐式 Fill.Aux[length.N, None.type, T]Out 类型相同 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

*->*[Option]#λ 可以在 def natLength.

中进行上下文绑定