Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala generic function that converts string to generic type

Tags:

generics

scala

I have a function that should find command-line parameter with it's value and return converted to type P:

def parameter[P](name: String)(implicit tag: ClassTag[P]): P = {

    val paramName = s"--$name"

    args.sliding(2, 2).toList.collectFirst {
      case Array(`paramName`, param: String) => {
        // if P is Int => param.toInt
        // if P is Double => param.toDouble
      }
    }.get
  }

How do I do that? I've found that ClassTag is a way to go, but can't figure out how to use it in this case.

like image 249
Yevhen Kuzmovych Avatar asked May 31 '26 20:05

Yevhen Kuzmovych


1 Answers

You can compare the class tag to tags for the types you want to match:

import scala.reflect.{ClassTag, classTag}

def parameter[P](args: Array[String], name: String)(implicit tag: ClassTag[P]): P = {
  val paramName = s"--$name"

  args.sliding(2, 2).toList.collectFirst {
    case Array(`paramName`, param: String) => (
      if (tag == classTag[Double]) {
        param.toDouble
      } else if (tag == classTag[Int]) {
        param.toInt
      } // and so on...
    ).asInstanceOf[P]
  }.get
}

You could also use pattern matching or whatever, of course. It works as expected:

scala> parameter[Int](Array("--foo", "123"), "foo")
res0: Int = 123

scala> parameter[Double](Array("--foo", "123"), "foo")
res1: Double = 123.0

There are lots of downsides to this approach, though—you have to know all the types you want to parse in the definition of parameter, etc.—and you're probably better off with a proper type class specifically designed for the kind of parsing you're doing.

like image 146
Travis Brown Avatar answered Jun 03 '26 21:06

Travis Brown



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!