views:

210

answers:

3

I had a List of Scala tuples like the following:

val l = List((1,2),(2,3),(3,4))

and I wanted to map it in a list of Int where each item is the sum of the Ints in a the corresponding tuple. I also didn't want to use to use the x._1 notation so I solved the problem with a pattern matching like this

def addTuple(t: (Int, Int)) : Int = t match { 
    case (first, second) => first + second 
}
var r = l map addTuple

Doing that I obtained the list r: List[Int] = List(3, 5, 7) as expected. At this point, almost by accident, I discovered that I can achieve the same result with an abbreviated form like the following:

val r = l map {case(first, second) => first + second}

I cannot find any reference to this syntax in the documentation I have. Is that normal? Am I missing something trivial?

+3  A: 

{case(first, second) => first + second} is treated as a PartialFunction literal. See examples in "Partial Functions" section here: http://programming-scala.labs.oreilly.com/ch08.html or section 15.7 of Programming in Scala.

Alexey Romanov
+10  A: 

See Section 8.5 of the language reference, "Pattern Matching Anonymous Functions".

An anonymous function can be defined by a sequence of cases

{case p1 =>b1 ... case pn => bn }

which appear as an expression without a prior match. The expected type of such an expression must in part be defined. It must be either scala.Functionk[S1, ..., Sk, R] for some k > 0, or scala.PartialFunction[S1, R], where the argument type(s) S1, ..., Sk must be fully determined, but the result type R may be undetermined.

The expected type deternines whether this is translated to a FunctionN or PartialFunction.

scala> {case x => x}  
<console>:6: error: missing parameter type for expanded function ((x0$1) => x0$1 match {
  case (x @ _) => x
})
       {case x => x}
       ^

scala> {case x => x}: (Int => Int)
res1: (Int) => Int = <function1>

scala> {case x => x}: PartialFunction[Int, Int]
res2: PartialFunction[Int,Int] = <function1>
retronym
+1  A: 

Method map accepts a function. In your first example you create a function, assign it to a variable, and pass it to the map method. In the second example you pass your created function directly, omitting assigning it to a variable. You are doing just the same thing.

folone
Not precisely. In the first example, the *method* `addTuple` is defined. The compiler then uses *partial application* to generate an equivalent function which is passed to the `map` method invoked on `l`.
Randall Schulz