【发布时间】:2021-02-17 03:15:35
【问题描述】:
我正在通过 Shapeless 学习方法,并且我希望实现一个特定的行为,以允许我们的代码以相同的方式扩展可选案例类,无论它们是否存在。基本上:
给定一个Option[N],其中N <: Product,我想生成一个HList,它与Generic[N].to 生成的类型相同,但每个元素都包含在Option 中(如果还没有的话)。例如:
case class Foo(a: String, b: Option[Long], c: Option[String])
optionalize[Foo](Some(Foo("abc", Some(123L), None)))
// => Some("abc") :: Some(123L) :: None :: HNil
optionalize[Foo](None)
// => None :: None :: None :: HNil
// where optionalize.Out = Option[String] :: Option[Long] :: Option[String] :: HNil
我的最终目标是扁平化嵌套案例类的能力,因此我想将其作为一项规则引入,以便 Shapeless 可以通过类型推断自动执行此操作。我心中最大的障碍是理解如何编写None 案例。目前,我的代码如下所示:
trait LowPriEnsureOptional extends Poly1 {
implicit def somethingCase[In]: Case.Aux[In, Option[In]] = at(thing => Some(thing))
implicit val hnilCase: Case.Aux[HNil, HNil] = at(identity)
}
object EnsureOptional extends LowPriEnsureOptional {
implicit def optionCase[In <: Option[_]]: Case.Aux[In, In] = at(identity)
}
object OptionizeHlist {
def optionizeCaseClass[
CC <: Product,
R <: HList
](occ: Option[CC])(
implicit gen: Generic[CC] { type Repr = R },
optionalize: Mapper[EnsureOptional.type, R]
): optionalize.Out =
occ match {
case Some(cc) => optionalize.apply(gen.to(cc))
case None => ???
}
}
要写出None 案例,我需要一些方法,给定一个案例类,获取它的通用repr,通过OptionizeHlist 运行它,并生成一个完全由Nones 组成的实例,但是我不知道从哪里开始。
【问题讨论】: