Scala 在未成形的产品上扩展选项[u3;]

Scala 在未成形的产品上扩展选项[u3;],scala,generics,shapeless,Scala,Generics,Shapeless,我正在通过Shapeless学习我的方法,我希望实现一个特定的行为,允许我们的代码以相同的方式扩展可选的案例类,无论它们是否存在。基本上: 给定一个选项[N]其中N一些(“abc”)::一些(123L)::无::HNil 选项化[Foo](无) //=>无::无::无::HNil //其中optionalize.Out=Option[String]::Option[Long]::Option[String]::HNil 我的最终目标是能够平展嵌套的case类,因此我想将其作为一条规则引入,以便

我正在通过Shapeless学习我的方法,我希望实现一个特定的行为,允许我们的代码以相同的方式扩展可选的案例类,无论它们是否存在。基本上:

给定一个
选项[N]
其中
N一些(“abc”)::一些(123L)::无::HNil
选项化[Foo](无)
//=>无::无::无::HNil
//其中optionalize.Out=Option[String]::Option[Long]::Option[String]::HNil
我的最终目标是能够平展嵌套的case类,因此我想将其作为一条规则引入,以便Shapeless可以通过类型推断自动完成这项工作。我脑海中最大的障碍是理解如何编写
None
案例。目前,我的代码如下所示:

trait低优先级可选扩展Poly1{
隐式def somethingCase[In]:Case.Aux[In,Option[In]]=at(thing=>Some(thing))
隐式val-hnilCase:Case.Aux[HNil,HNil]=at(identity)
}
对象EnsureOptional扩展到LowPriEnsureOptional{

implicit def optionCase[在中注意,如果向您传递了一个
None
,则键入erasure将使您无法知道要将多少
None
放入输出列表中。因此,您需要另一个implicit参数才能在运行时保存该信息

final class AllNoneable[H <: HList] private (val allNone: H) extends AnyVal
object AllNoneable {
    implicit val allNoneableHNil = new AllNoneable[HNil](HNil)
    implicit def allNoneableCons[H >: None.type, T <: HList](implicit t: AllNoneable[T])
    = new AllNoneable[H :: T](None :: t.allNone)
}

trait LowPriEnsureOptional extends Poly1 {
  implicit def somethingCase[In]: Case.Aux[In, Option[In]] = at(Some(_))
}
object EnsureOptional extends LowPriEnsureOptional {
  implicit def optionCase[In <: Option[_]]: Case.Aux[In, In] = at(identity)
}
def optionalizeCase
  [C, Rep <: HList, Opt <: HList](c: Option[C])
  (implicit
    gen: Generic.Aux[C, Rep], opt: Mapper.Aux[EnsureOptional.type, Rep, Opt],
    nones: AllNoneable[Opt]): Opt
= c match {
    case Some(c) => opt.apply(gen.to(c))
    case None => nones.allNone
}