0

I am trying to create a map of lambda functions in Scala

val identity = ((x:Any) => x)
val propmap = Map("references-count" -> identity, 
    "title" -> ((x:List[String]) => x(0)),
    "score" -> identity,
    "issued" -> ((x:List[Any]) => x(0)))

when I type propmap("score") or propmap("title") the output I get is the same: <function1>.

Running identity(10.1) returns the expected result. However

val f1 = propmap("score") f1(10.9)

results in:

Name: Unknown Error
Message: <console>:29: error: type mismatch;
 found   : Double(10.9)
 required: List[String]
       f1(10.9)
          ^
StackTrace: 

Seemingly the function is overwritten. Where to go for the besung immutabilty?

1
  • Look at the type of propmap. And besides, this error is compile time error, you can't infer anything about the runtime properties of your program based on it. Commented Apr 15, 2017 at 0:22

2 Answers 2

2

The problem is the type of propmap.

Scala infers the type as String, (List[String] => Any)

The reason for that is that scala needs to infer a type which matches ALL values. The String as key is obvious but for the function, it needs to find a function type which matches all functions. Since all functions have 1 parameter this would be function1.

If you look at the definition of function1 you would see it is:

trait Function1[-T1, +R] extends AnyRef

This means that it needs to find the first type to be the most constrictive. In this case this is List[String] and therefore it expects a function List[String]=>Any (this actually makes sense because you want a type you can use on ALL functions).

So scala automatically converts your identity function to be (x: List[String] => x) in practice and therefore when you try to pass it a number it fails.

Possible solutions:

The first solution as mentioned by @KotWarm would be to use asInstanceOf:

val f1 = propmap("score").asInstanceOf[Any ⇒ Any]
println(f1(10.9))

The second solution would be to rewrite the functions to use Any, for example:

val propmap = Map("references-count" -> identity,
                  "title" -> ((x: Any) => x.asInstanceOf[List[String]](0)),
                  "score" -> identity,
                  "issued" -> ((x: Any) => x.asInstanceOf[List[Any]](0)))
Sign up to request clarification or add additional context in comments.

2 Comments

how can I check the definition?
1

Because scalac determined the type of collection as

propmap: scala.collection.immutable.Map [String, List [String] => Any]

Determine the type of your collection explicitly so that the compiler knows what you want to get

Here is an example code

    val identity = ((x:Any) => x)
    val propmap = Map[String,_ => _]("references-count" -> identity,
        "title" -> ((x:List[String]) => x(0)),
        "score" -> identity,
        "issued" -> ((x:List[Any]) => x(0)))

But to execute the methods you must cast the type

    val f1 = propmap("score").asInstanceOf[Any ⇒ Any]
    println(f1(10.9))

1 Comment

You actually do not need to qualify the Map statement, the original definition of propmap would work, you just need the asInstanceOf

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.