Bernie Wong
Bernie Wong

Reputation: 701

how to create a parameterized function to check values of varying types

Assume I have to check the values in a hash map of name/value pairs that was read in from a file to see if the values meet certain requirements or constraints.

val hm: mutable.HashMap[String, String] = mutable.HashMap()
hm.put("abc", 123)
hm.put("def", "xYx") 

I would like to write simple checks like the ones below. For example,

evaluate("abc", 125, (x,y) => x == y)  // see if value of "abc" is equal to 125 (integer)
evaluate("def", "xyz", (x,y) => x.toLowerCase == y) // sse if the value of def is equal to xyz (all lower case) 
evaluate("abc", 400, (x,y) => x > y) // see if value is greater than 400

I have tried creating the evaluate function as follows

def evaluate[T](p: String, expVal: T, f: (T, T) => Boolean): Boolean =  {
    if (!hm.contains(p)) false

    typeOf[T] match {
        case t if t =:= typeOf[String] => f(hm(p), expVal)
        case t if t =:= typeOf[Int] => f(hm(p).toInt, expVal)
        case _ => false
    }
}

When I run the above, I get

Error:(16, 11) No TypeTag available for T
    typeOf[T] match {

Error:(16, 11) not enough arguments for method typeOf: (implicit ttag: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type.
    Unspecified value parameter ttag.
    typeOf[T] match {

Error:(17, 45) type mismatch;
  found   : String
  required: T
  case t if t =:= typeOf[String] => f(hm(p), expVal)

I was wondering if you have better suggestions for the evaluate function.

Thanks in advance.

Upvotes: 0

Views: 41

Answers (1)

Tim
Tim

Reputation: 27421

Your Map type is [String, String] so you will always get a value of type String from it. Therefore your attempts to test the type of the value don't achieve anything because it is always String.

If you want to keep this map type, then you need to convert values as necessary, You can also make the test values part of the test function rather than passing them in as separate arguments to evaluate.

def evaluate(key: String, pred: String => Boolean) =
  hm.get(key).exists(pred)

evaluate("abc", _.toInt == 125) // see if value of "abc" is equal to 125 (integer)
evaluate("def", _.toLowerCase == "xyz") // sse if the value of def is equal to xyz (all lower case)
evaluate("abc", _.toInt > 400) // see if value is greater than 400

The first and third expressions will fail if the value cannot be converted to Int.

Upvotes: 1

Related Questions