Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to match on the type of a manifest in Scala?

Tags:

scala

I'm writing some code in Scala that depends a the type parameter that I can't see on an argument.

def read[T](json: String)(implicit m: Manifest[T]): T = {
  if (m <:< manifest[Map[String, Any]]) {
    JsonParser.jsonToMap(json).asInstanceOf[T]
  } else {
    throw new UnsupportedOperationException("Not implemented for type %s".format(m))
  }
}

Apart from the fact that I'm writing my own json framework, which is probably a pretty bad idea...

Can I use a case statement instead of the if statements, or should I be thinking in a different direction?

like image 907
iwein Avatar asked Nov 20 '25 04:11

iwein


1 Answers

A much better idea in situations like these where you feel tempted to use sequences of tests against manifests or classes (or type casing more generally) is to use a type class. In this particular case it would look like,

// Type class
trait JsonReader[T] {
  def apply(json : String) : T
}

// Type class instance for type Map[String, Any]
implicit def mapReader = new JSonReader[Map[String, Any]] {
  def apply(json : String) =
    JsonParser.jsonToMap(json).asInstanceOf[Map[String, Any]]
}

def read[T](json : String)(implicit reader : JsonReader[T]) : T = reader(json)

You should add type instances for all of the types that you care about.

You can now call your read function as follows,

read[Map[String, Any]](... some json ...)

Note that now if you attempt to call it with a type parameter corresponding to a type for which you haven't provided a type class instance the result will be an error at compile time rather than an UnsupportedOperationException at runtime.

like image 66
Miles Sabin Avatar answered Nov 21 '25 19:11

Miles Sabin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!