我使用的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 = ???
}
这是一种解决方法,无法隐藏从此回答https://stackoverflow.com/a/5736428/247623中获取的自动生成的案例类伴随apply
到完全不相关的问题。
虽然它的工作范围令人满意 - 除了编译错误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)
}
......或类似的。