1

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.

Community
  • 1
  • 1
Erik Kaplun
  • 33,421
  • 12
  • 92
  • 102

0 Answers0