6

I have a map with a getter method. The key is always a String, the value is Any. I want to allow the caller to use a method like the followings

get[Int](k: String)
get[Boolean](k:String)

and inside this method convert the string to the specific type specified by the user. The immediate solution came to my mind was

def get[T](k: String): T = k.asInstanceOf[T]

which does not work. Then I tried with

def cast[T](x: String, classTag: ClassTag[T]): T = classTag match {
   case Int => x.toInt
   case Boolean => x.toBoolean
   ...
}  

which does not compile. I am not sure this is even possible. Any idea or I need to write all the methods I want? For example

def getInt(k: String): Int
def getBoolean(k: String): Boolean
...

2 Answers 2

5

This is a classical use case for typeclass pattern widely used in scala. I assume that you have a custom implementation of Map and get method.

trait Converter[T]{        // typeclass
  def convert(t:String):T
}

implicit object ToIntConverter extends  Converter[Int] {
  def convert(t:String):Int = t.toInt
}


implicit object ToBooleanConverter extends  Converter[Boolean] {
  def convert(t:String):Boolean = t.toBoolean
}

//       vvv approach bellow works starting from scala 2.12 vvv
//
// implicit val ToBooleanConverter: Converter[Boolean] = s => s.toBoolean 
// implicit val ToIntConverter : Converter[Int]  = s => s.toInt 


def get[T](k:String)(implicit cv: Converter[T]):T= cv.convert(k)


println(get[Int]("1"))
println(get[Boolean]("true"))
Sign up to request clarification or add additional context in comments.

1 Comment

thanks! it works. A bit verbose but works. I am using scala 2.11.8 and it is working as well by the way
2

I got the below to work.

val anyMap: Map[String, Any] = Map(
  "a" -> 1,
  "b" -> true
)

def getInst[T](amap: Map[String, Any])(k: String): T = amap.get(k) match {
  case Some(thing) => thing.asInstanceOf[T]
  case None => throw new IllegalArgumentException
}

getInst[Int](anyMap)("a")
getInst[Boolean](anyMap)("b")

It's not very safe to have something like Map[String, Any] as the cast might fail. Probably best to introduce some ad-hoc polymorphism in your map (not sure).

1 Comment

this works but I don't want to simply get the instance but, in some cases, I need also to convert it. For example, if "a" -> "1" and I call getInst[Int](anyMap)("a") this would fail

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.