I don't think there is a way to write the function as such with Manifest
, ClassTag
or a TypeTag
as they can only tell you the type at runtime. For something like the pseudocode function to work, the return type must be known at compile time.
However, could implement the function by defining a type class and writing instances for the types you wish to cast from. Here's an example:
import java.lang.Double.parseDouble
import java.lang.Integer.parseInt
trait CastableFromString[A] {
def fromString(string: String): A
}
object CastableFromString {
implicit object DoubleCastableFromString extends CastableFromString[Double] {
override def fromString(string: String): Double =
parseDouble(string)
}
implicit object IntCastableFromString extends CastableFromString[Int] {
override def fromString(string: String): Int =
parseInt(string)
}
implicit object IntListCastableFromString extends CastableFromString[List[Int]] {
override def fromString(string: String): List[Int] =
string.split(',').map(parseInt).toList
}
def castFromString[A](string: String)(implicit cast: CastableFromString[A]): A =
cast.fromString(string)
}
object Main {
import CastableFromString._
def main(args: Array[String]): Unit = {
val d = castFromString[Double]("4.5")
val i = castFromString[Int]("42")
val li = castFromString[List[Int]]("1,2,3")
println(s"d=$d i=$i li=$li")
}
}
Alternatively, to get closer to something that resembles your pseudocode, you could use a macro. Here's an example (won't work on anything older than Scala 2.11):
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
class StringCasterImpl(val c: Context) {
def castFromStringImpl[A: c.WeakTypeTag](string: c.Expr[String]): c.Tree = {
import c.universe._
val t = c.weakTypeOf[A]
if (t =:= typeOf[Double]) {
q"java.lang.Double.parseDouble($string)"
} else if (t =:= typeOf[Int]) {
q"java.lang.Integer.parseInt($string)"
} else if (t =:= typeOf[List[Int]]) {
q"$string.split(',').map(java.lang.Integer.parseInt).toList"
} else {
c.abort(c.enclosingPosition, s"Don't know how to cast $t to String")
}
}
}
object StringCaster {
def castFromString[A](string: String): A =
macro StringCasterImpl.castFromStringImpl[A]
}
// note that this object must be in a separate compilation unit
object Main {
import StringCaster._
def main(args: Array[String]): Unit = {
val d = castFromString[Double]("4.2")
val i = castFromString[Int]("42")
val li = castFromString[List[Int]]("1,2,3")
println(s"d=$d i=$i li=$li")
}
}