【发布时间】:2016-06-22 15:44:20
【问题描述】:
这是这个问题的部分重复:Getting subclasses of a sealed trait,但答案建议运行时反射,这对我来说不合适,我想知道它是否可以在编译时使用,可能使用 Shapeless。
所以,有了这个 ADT:
sealed trait ColumnAttribute
case class Default(value: String) extends ColumnAttribute
case class Identity(seed: Int, step: Int) extends ColumnAttribute
case class Encode(encoding: CompressionEncoding) extends ColumnAttribute
case object DistKey extends ColumnAttribute
我怎样才能得到像Option[Default] :: Option[Identity] :: Option[Encode] :: Option[DistKey] :: HNil 这样的东西?
更具体的问题(可能我正在寻找错误的解决方案)。
拥有以上 AST 和以下类,我怎么能确定在编译时 Column 不会被多个 Encode 或 DistKey 或其他 ColumnAttribute 构造。
case class Column(columnName: String, dataType: DataType, columnAttributes: Set[ColumnAttribute], columnConstraints: Set[ColumnConstraint])
UPD:columnAttributes 应该只包含一个特定子类型的值,但可以包含多个不同子类型的值。
所以,这个伪代码应该是正确的:
columnConstraint = Default("foo") :: DistKey :: Identity(1,2) :: HNil
但这应该会失败:
columnConstraint = Default("foo") :: Default("bar") :: HNil
【问题讨论】:
-
这里可能漏掉了重点,但是为 Column 添加了一个自定义的应用方法?验证施工?
-
好吧,我已经考虑过了。因为有太多方法可以构造无效值(例如负数
step),甚至不考虑这些集合,所以总体而言它可能不值得。但是出于好奇,问题仍然有效。 -
我不确定你在尝试什么,但既然你提到了 shapeless 甚至提供了一个例子:选项的 HList 并不是 ADT 的真正公平表示。 HLists 是产品,你需要一个副产品:github.com/milessabin/shapeless/wiki/…
-
嘿@pedrofurla!对我来说,它看起来更像是一种产品。因为 coproduct 假设我们有一个值是
DistKeyorEncodeor 另一个ColumnAttribute,但我需要的是可选 @987654337 的(可能是空的)乘积@和可选Encode等
标签: scala abstract-syntax-tree shapeless type-level-computation