微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何获取联产品的所有可能成员

如何解决如何获取联产品的所有可能成员

我一直在尝试列出联产品类型的所有成员。这 answer 非常接近我想要达到的目标:

sealed trait Traity
case object Foo  extends Traity
case class Bar() extends Traity
case class Baz() extends Traity

import shapeless._

class NameHelper[A] {
  def apply[C <: coproduct,K <: HList]()(
    implicit
    gen: LabelledGeneric.Aux[A,C],keys: ops.union.Keys.Aux[C,K],toSet: ops.hlist.ToTraversable.Aux[K,Set,Symbol]): Set[String] = toSet(keys()).map(_.name)
}

def names[A] = new NameHelper[A]

names[Traity]()

具有预期的输出

res0: Set[String] = Set(Bar,Baz,Foo)

但我的源类型不是密封特性,它是原始的无形副产品。我尝试了以下方法,但无法编译:

type ISB = Int :+: String :+: Boolean :+: CNil

class NameHelper2[A <: coproduct] {
  def apply[K <: HList]()(
    implicit
  keys: ops.union.Keys.Aux[A,Symbol]): Set[String] = toSet(keys()).map(_.name)
}

def names2[A <: coproduct] = new NameHelper2[A]

names2[ISB]()

结果是一个缺失的隐含值:

Could not find implicit value for parameter keys: shapeless.ops.union.Keys.Aux[ISB,K]
names2[ISB]()

我想要的是可能的副产品成员:Set(Int,String,Boolean)

提前致谢。

解决方法

没那么近。在那里提取现有的键,在这里创建类型的文本表示。

你可以做到

class NameHelper2[C <: Coproduct] {
  def apply[L <: HList,L1 <: HList]()(
    implicit
    toHList: ops.coproduct.ToHList.Aux[C,L],fillWith: ops.hlist.FillWith[nullPoly.type,mapper: ops.hlist.Mapper.Aux[typeablePoly.type,L,L1],toSet: ops.hlist.ToTraversable.Aux[L1,Set,String]): Set[String] = toSet(mapper(fillWith()))
}

object nullPoly extends Poly0 {
  implicit def cse[X]: Case0[X] = at(null.asInstanceOf[X])
}

object typeablePoly extends Poly1 {
  implicit def cse[X](implicit typeable: Typeable[X]): Case.Aux[X,String] = at(_ => typeable.describe)
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。