我正在使用只能在验证步骤之后构建的 ADT(这是 FP 中的常见做法,以确保正确性)。例如,我在 上使用一个Score
类型Double
,它验证其包装值在 [0.0, 100.0] 内。
所以我有这样的事情:
case class Score private(raw: Double) extends AnyVal
object Score {
def mk(raw: Double) = (0 <= raw && raw <= 100) option new Score(raw)
// XXX: WOULD LIKE TO GET RID OF THIS LINE:
def apply(raw: Double)(implicit ev: DummyImplicit): Score = ???
}
这是一种解决方法,无法隐藏apply
从这个答案https://stackoverflow.com/a/5736428/247623获取的自动生成的案例类伴侣到一个完全不相关的问题。
尽管它在令人满意的程度上工作——除了编译错误ambiguous reference to overloaded definition
根本没有帮助——它具有每个 ADT 定义的巨大缺点,一个受保护的构造函数必须显式定义:
def apply(raw: Double)(implicit ev: Nothing): Score = notAllowed
我试过使用继承无济于事。
是否有可能使用宏来实现这一点,或者 Scala 宏当前不支持向类/对象添加方法?就像是:
case class Score private(raw: Double) extends AnyVal
@guarded object Score {
def mk(raw: Double) = (0 <= raw && raw <= 100) option new Score(raw)
}
...或类似的。