views:

129

answers:

3

Suppose I have a simple class in Scala:

class Simple {
  def doit(a: String): Int = 42
}

How can I store in a val the Function2[Simple, String, Int] that takes two arguments (the target Simple object, the String argument), and can call doit() get me the result back?

+9  A: 
val f: Function2[Simple, String, Int] = _.doit(_)
sepp2k
Called "partial application." As show here it's a special case. As the name suggests, some arguments may be supplied in the partial application and the resulting function has arity N-M where N was the original method's (or function's) arity and M is the number of arguments fixed in the partial application.
Randall Schulz
Perfect. I was wondering how the compiler would figure out whether the doit method really exists; I see that explicit typing does the trick here. Thanks!
JPP
+6  A: 

same as sepp2k, just using another syntax

val f = (s:Simple, str:String) => s.doit(str)
hbatista
+7  A: 

For those among you that don't enjoy typing types:

scala> val f = (_: Simple).doit _
f: (Simple) => (String) => Int = <function1>

Following a method by _ works for for any arity:

scala> trait Complex {                        
     |    def doit(a: String, b: Int): Boolean
     | }                                      
defined trait Complex

scala> val f = (_: Complex).doit _            
f: (Complex) => (String, Int) => Boolean = <function1>

This is covered by a combination of §6.23 "Placeholder Syntax for Anonymous Functions" and §7.1 "Method Values" of the Scala Reference

retronym
What are the practical implications of having a function of type (Simple) => (String) => Int vs. of type (Simple, String) => Int? I know the former is called with f(obj)("str") and the latter with f(obj, "str"), and the former returns another function object if just call it with one parameter list: f(obj).But what happens behind the scenes in terms of number of objects created and number of method invocations?
JPP
Two Function1 objects rather than one Function2 object is created, with an extra level of indirection.
retronym