8

While creating a map of String to partial functions I ran into unexpected behavior. When I create a partial function as a map element it works fine. When I allocate to a val it invokes instead. Trying to invoke the check generates an error. Is this expected? Am I doing something dumb? Comment out the check() to see the invocation. I am using scala 2.7.7

def PartialFunctionProblem() = {
    def dream()() = {
        println("~Dream~");
        new Exception().printStackTrace()
    }
    val map = scala.collection.mutable.HashMap[String,()=>Unit]()
    map("dream") = dream()      // partial function
    map("dream")()              // invokes as expected
    val check = dream()         // unexpected invocation
    check()                     // error: check of type Unit does not take parameters 
}
1
  • Thanks for the help. When I replaced my dream() calls with dream()_ it behaved as I expected. I'll go out and read more on PartialFunctions so I don't misuse the term again. Commented May 21, 2010 at 0:26

2 Answers 2

12

For convenience, Scala lets you omit empty parens when calling a method, but it's clever enough to see that the expected type in the first case is ()=>Unit, so it doesn't remove all the parens for you; instead, it converts the method into a function for you.

In the val check case, however, it looks just like a function call result getting assigned to a variable. In fact, all three of these do the exact same thing:

val check = dream
val check = dream()
val check = dream()()

If you want to turn the method into a function, you place _ after the method in place of the argument list(s). Thus,

val check = dream() _

will do what you want.

Sign up to request clarification or add additional context in comments.

Comments

5

Well, the problem is that you got it all wrong. :-)

Here are some conceptual mistakes:

def dream()() = {
    println("~Dream~");
    new Exception().printStackTrace()
}

This is not a partial function. This is a curried method with two empty parameter lists which returns Unit.

val map = scala.collection.mutable.HashMap[String,()=>Unit]()

The type of the values in this map is not partial function, but function. Specifically, Function0[Unit]. A partial function would have type PartialFunction[T, R].

map("dream") = dream()      // partial function

What happens here is that Scala converts the partially applied method into a function. This is not a simple assignment. Scala does the conversion because the type inferencer can guess the correct type.

val check = dream()         // unexpected invocation

Here there's no expected type to help the type inferencer. However, empty parameter lists can be ommitted, so this is just a method call.

Comments

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.