scala - How to obtain all possible members of a coproduct
问题描述
I've been trying to list all the members of a coproduct type. This answer is really close to what I want to achive:
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]()
With the expected output:
res0: Set[String] = Set(Bar, Baz, Foo)
But my source type is not a sealed trait, It's a raw shapeless coproduct. I've tried the following approach, but it does not compile:
type ISB = Int :+: String :+: Boolean :+: CNil
class NameHelper2[A <: Coproduct] {
def apply[K <: HList]()(
implicit
keys: ops.union.Keys.Aux[A, K],
toSet: ops.hlist.ToTraversable.Aux[K, Set, Symbol]): Set[String] = toSet(keys()).map(_.name)
}
def names2[A <: Coproduct] = new NameHelper2[A]
names2[ISB]()
The outcome is a missing implicit value:
could not find implicit value for parameter keys: shapeless.ops.union.Keys.Aux[ISB,K]
names2[ISB]()
What I want is the possible coproduct members: Set(Int, String, Boolean)
Thanks in advance.
解决方案
It's not so close. There you extract existing keys, here you create textual representation of types.
You can do
class NameHelper2[C <: Coproduct] {
def apply[L <: HList, L1 <: HList]()(
implicit
toHList: ops.coproduct.ToHList.Aux[C, L],
fillWith: ops.hlist.FillWith[nullPoly.type, L],
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)
}
推荐阅读
- javascript - 如何在 Sweet Alert 弹出消息内容中获得价值?
- html - 无论设备类型如何,如何在 HTML 和 CSS 中将动画图像和非动画文本居中?
- http - Nginx 客户端发送了重复的标题行?
- java - 哪一个执行得更快?sql order by 或 java PriorityQueue 或任何其他?
- reporting-services - SSRS 向下钻取报告未正确过滤参数
- python - 使用循环返回顺序在列表中搜索字符串
- python - 如何使用 executemany 将每个 Key 中的第一个值写入数据库
- javascript - 从 React.js 中的 div 获取 ID
- php - PHP AJAX多表单未插入数据库
- ios - 无效的 Swift 支持 - 文件不在预期的位置