3

In an earlier question about zipWith, @Martin Odersky suggested that instead of something like

 foo zipWith(_ + _) bar

(where foo and bar are Seq's) that the following is better (and actually works in Scala).

(foo, bar).zipped map (_ + _)

My question is how does map know that its argument (which superficially would seem to be a pair) should be split into its two elements?

The following actually runs in a worksheet.

val list1 = List(1, 2, 3, 4)                    //> list1  : List[Int] = List(1, 2, 3, 4)
val list2 = List(5, 6, 7, 8)                    //> list2  : List[Int] = List(5, 6, 7, 8)
val zippedResult = (list1, list2).zipped        //> list3  : scala.runtime.Tuple2Zipped[Int,List[Int],Int,List[Int]] = scala.run
                                              //| time.Tuple2Zipped@f4bf78da
zippedResult.mkString(", ")                     //> res4: String = (1,5), (2,6), (3,7), (4,8)
zippedResult map (_ + _)                        //> res5: List[Int] = List(6, 8, 10, 12)

I see that zippedResult in fact has 4 type parameters and is not just a list of pairs.

val list3 = List((1, 5), (2, 6), (3, 7), (4, 8))
                                              //> list3a  : List[(Int, Int)] = List((1,5), (2,6), (3,7), (4,8))
list3 == zippedResult                           //> res6: Boolean = false

And I can't write

list3 map(_ +_ )

So what is the Tuple2Zipped type that it can supply two parameters to the map function? And is zipped the only way to create instances of it?

Community
  • 1
  • 1
RussAbbott
  • 2,660
  • 4
  • 24
  • 37
  • 1
    While you can't write `map(_ + _)` for a `.zipped` sequence, you can still use case matching to get at the individual elements: `list3 map { case (a,b) => a+b }`. Not as short, but it's something. – KChaloux Feb 14 '14 at 18:17

1 Answers1

5

It's runtime.Tuple2Zipped. You can create an instance manually like this:

val zipped = new Tuple2Zipped(Seq(1, 2), Seq(3, 4))

Here is the source of map method.

Method map is declared like this (simplified):

def map[B](f: (El1, El2) => B): Seq[B]

Tuple2Zipped is not an descendant of any scala collection type, so its map method has nothing with map method of regular scala collections.

senia
  • 37,745
  • 4
  • 88
  • 129
  • Thanks for the answer. It makes sense that it would be a special case and that its `map` would be different from all the other `map`'s. I'm surprised that this hasn't received more publicity. – RussAbbott Feb 13 '14 at 18:21
  • That's quite a discovery, never thought there's something collection-like but standing apart. Also there's `Tuple3Zipped`, which allows more funny constructs `(a, b, c).zipped map (_ * _ + _)`. That's a pity there is no continuation after 3. – dmitry Feb 13 '14 at 19:16