Yar Yar - 1 year ago 120
JSON Question

Scala pattern match multiple types

I have a code for extracting

that should look exactly the same for multiple
subclasses, so I'm trying to avoid repeating myself. However, as it is (see below), scala thinks that
is a generic
, and that
returns a value of type
, which, of course, does not have

jvalue \ name match {
case j @ (JInt | JDecimal | JDouble) => {
val num = j.values
if (num.isValidInt) num.toInt.success else reportError(name + " is not a valid int")

The question is what is the proper way to avoid repetition here? I'm not that crazy about converting a
into string, because this code works with json just parsed from a string into an AST. I started thinking about writing wrappers for the three types I need matched and implicit converters from these types into wrappers, and then making a superclass just for these wrappers for use as a pattern, but I am not sure how to pull it off.

And yes, I realize there are multiple similar questions here (such as this and this), but each of them only contains part of the solution at most.

Answer Source

Implement an extractor to get the Int value out of arbitrary json values, then use the extractor in your mattern match.

object JsonInt {
  def unapply(json: JValue): Option[Int] = json match {
    case JInt(i) if i.isValidInt => Some(i.toInt)
    case JDecimal(d) if d.isValidInt => Some(d.toInt)
    case JDouble(d) if d.isValidInt => Some(d.toInt)
    case _ => None

jvalue \ name match {
  case JsonInt(num) => num.success
  case _ => reportError(s"$name is not a valid int")
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download