aa8y aa8y - 3 months ago 22
Scala Question

Adding an implicit getAs() method to Scala Maps

So I want to add an implicit method which would return the value for a key by checking its type.

import scala.reflect.ClassTag

object MyMap {
implicit class FlexMap[A](map: Map[String, A]) {
def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = map.get(key) match {
case Some(value: ct.runtimeClass) => Some(value.asInstanceOf[B])
case _ => None
}
}
}


But when I try and compile this, I get:


type runtimeClass is not a member of scala.reflect.ClassTag[B]


I get the same error even if I use:

case Some(value) if (value.isInstanceOf[ct.runtimeClass])


I am not sure how to get around this. Any ideas?

Answer

in Scala a type is not a value, they are in different categories, so type can't be returned from a method. .runtimeClass in fact returns a value of type Class which can't be used where a type is expected. What you probably need is this:

object MyMap {
  implicit class FlexMap[A](map: Map[String, A]) {
    def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = map.get(key) match {
      case Some(value: B) => Some(value)
      case _ => None
    }
  }
}

Another way of saying the same thing:

def getAs[B](key: String)(implicit ct: ClassTag[B]): Option[B] = 
  map.get(key) flatMap {
    case value: B => Some(value)
    case _        => None
  }