I'm using ADTs that should only be able to be constructed after a validation step (which is common practice in FP to ensure correctness). As an example, I'm using a Score
type on top of Double
, which validates its wrapped value to be within [0.0, 100.0].
So I have something like this:
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 = ???
}
It's a workaround to it not being possible to hide the auto-generated case class companion apply
taken from this answer https://stackoverflow.com/a/5736428/247623 to a completely unrelated question.
Whereas it works to a satisfactory extent — except for the compilation error ambiguous reference to overloaded definition
not at all being helpful — it has the huge downside of the definition of each ADT with a guarded constructor having to explicitly define this:
def apply(raw: Double)(implicit ev: Nothing): Score = notAllowed
I've tried using inheritance to no avail.
Is it at all possible to achieve this using macros or do Scala macros not currently support adding of methods to a class/object? Something like:
case class Score private(raw: Double) extends AnyVal
@guarded object Score {
def mk(raw: Double) = (0 <= raw && raw <= 100) option new Score(raw)
}
...or similar.