I have a number of functions like this:
// Convert a string to integer, defaulting to 0 if it fails
def safeToInt(s: String): Int = try {
s.toInt
} catch {
case _: NumberFormatException => 0
}
// Convert a string to long, defaulting to 0 if it fails
def safeToLong(s: String): Long = try {
s.toLong
} catch {
case _: NumberFormatException => 0
}
// Convert a string to double, defaulting to 0 if it fails
def safeToDouble(s: String): Double = try {
s.toDouble
} catch {
case _: NumberFormatException => 0
}
Any way to make these cleaner? They essentially all do the same thing apart from one line.
You can take advantage of Numeric
to avoid duplicating the zero.
import scala.util.Try
def safeToNumeric[A: Numeric](f: String => A)(s: String): A =
Try(f(s)).getOrElse(implicitly[Numeric[A]].zero)
val safeToInt = safeToNumeric(_.toInt)(_)
val safeToLong = safeToNumeric(_.toLong)(_)
val safeToDouble = safeToNumeric(_.toDouble)(_)
safeToInt("4") // 4
safeToDouble("a") // 0.0
Unfortunately Numeric
doesn't give you the parsing method as well, but you can create the appropriate type class yourself ...
case class Parser[A](parse : String => A)
implicit val intParser = Parser(_.toInt)
implicit val longParser = Parser(_.toLong)
implicit val doubleParser = Parser(_.toDouble)
... and then you can write a single method that works for all of the types.
def safeTo[A: Parser : Numeric](s: String): A =
Try(implicitly[Parser[A]].parse(s))
.getOrElse(implicitly[Numeric[A]].zero)
safeTo[Int]("4") // 4
safeTo[Double]("a") // 0.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With