Reputation: 2737
I want to call map()
on a list of pairs, but I get a type mismatch error.
For example, suppose I want to map a List of pairs of Int to a list of their sums:
scala> val ll=List((1,2),(3,4),(5,6))
ll: List[(Int, Int)] = List((1,2), (3,4), (5,6))
scala> ll.map((x:Int,y:Int)=>x+y)
<console>:9: error: type mismatch;
found : (Int, Int) => Int
required: ((Int, Int)) => ?
ll.map((x:Int,y:Int)=>x+y)
^
By the way, when trying to run foreach() I get a very similar error:
scala> ll.foreach((x:Int,y:Int)=>println(x,y))
<console>:9: error: type mismatch;
found : (Int, Int) => Unit
required: ((Int, Int)) => ?
ll.foreach((x:Int,y:Int)=>println(x,y))
^
What does the ?
sign stand for? What am I missing here?
Upvotes: 28
Views: 27419
Reputation: 61766
Starting in Scala 3
, parameter untupling has been extended, allowing such a syntax:
List((1, 2), (3, 4), (5, 6)).map(_ + _)
// List(3, 7, 11)
where each _
refers in order to the associated tuple part.
Upvotes: 1
Reputation: 42045
You can use pattern matching to get the elements of the pair.
ll.map{ case (x:Int,y:Int) => x + y }
You don't even need to specify the types:
ll.map{ case (x, y) => x + y }
The same works with foreach
of course.
The error message tells you that the compiler expected to find a function of one parameter (a pair of ints) to any type (the question mark) and instead found a function of two parameters, both ints.
Upvotes: 47
Reputation: 51109
You can tuple a function, which means going from one that takes N args to one that takes 1 arg that is an N-tuple. The higher-order function to do this is available on the Function
object. This results in nice syntax plus the extra type safety highlighted in the comments to Brian Agnew's answer.
import Function.tupled
ll map tupled(_ + _)
Upvotes: 7
Reputation: 272417
You can use:
ll.map(x => x._1 + x._2)
where x
stands for the tuple itself, or
ll.map(x:(Int,Int) => x._1 + x._2)
if you want to declare the types explicitly.
Upvotes: 20