Scala Programming Language
  1. Scala Programming Language
  2. SI-1512

Addition of #zipWith Method to Standard Collections

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Misc Library
    • Labels:
      None

      Description

      Several collections in the Scala library have a #zip method. This method takes another collection and then merges it with the invocation target, producing a collection of type (A, B), where A is the component type of `this` and B is the component type of `that`.

      However, I do not believe that this method is general enough. It somewhat-arbitrarily decides that the best way to "merge" to collection elements is to wrap them together in a 2-tuple. This is fine for correctness, but most often the user of the API must take an extra step to "unwrap" these values in order to produce the desired result. This can be inefficient, and generally constitutes extra code which can obscure intent.

      I would request the addition of a #zipWith method (patterned after Haskell's function of the same name) to every collection which supports #zip. At a minimum, this method could be defined in terms of #zip and #map:

      def zipWith[B, C](that: List[B])(f: (A, B)=>C) = {
        this zip that map { case (x, y) => f(x, y) }
      }
      

      This is sub-optimal because it traverses the collection twice and produces an intermediary "throw-away" value, but it is the simplest approach.

      This method would be useful in a number of situations, including (but not limited to) everyone's favorite infinite series (assuming :: syntax for Streams):

      val fibs: Stream[Int] = 0 :: 1 :: fibs.zipWith(fibs.tail) { _ + _ }
      

      More generally though, I think it would be a more concise and more readable method in just about every situation where #zip would be applied. Logically, #zip is just a specialization of #zipWith, passing a function which takes two values and returns a tuple of the same.

        Activity

        Hide
        Seth Tisue added a comment -

        beware SI-2634, though

        Show
        Seth Tisue added a comment - beware SI-2634 , though
        Hide
        Daniel Spiewak added a comment -

        Replying to [comment:8 odersky]:
        > Instead of zipWith, there's now zipped. Usage:
        > {{
        > scala> val xs = List(1, 2, 3)
        > xs: List[Int] = List(1, 2, 3)
        >
        > scala> (xs, xs).zipped map (_ + _)
        > res1: List[Int] = List(2, 4, 6)
        > }}

        How is this an improvement over:

        val xs = List(1, 2, 3)
        xs zip xs map { _ + _ }
        

        In fact, it's actually longer.

        Show
        Daniel Spiewak added a comment - Replying to [comment:8 odersky] : > Instead of zipWith, there's now zipped. Usage: > {{ > scala> val xs = List(1, 2, 3) > xs: List [Int] = List(1, 2, 3) > > scala> (xs, xs).zipped map (_ + _) > res1: List [Int] = List(2, 4, 6) > }} How is this an improvement over: val xs = List(1, 2, 3) xs zip xs map { _ + _ } In fact, it's actually longer .
        Hide
        Seth Tisue added a comment -

        djspiewak: that doesn't compile.

        Show
        Seth Tisue added a comment - djspiewak: that doesn't compile.
        Hide
        Daniel Spiewak added a comment -

        Oh yeah. Obviously...

        Show
        Daniel Spiewak added a comment - Oh yeah. Obviously...
        Hide
        Martin Odersky added a comment -

        It's an improvement in two ways: (1) There's no intermediate list that's built. (2) It works for more than 2 lists in exactly the same way.

        Show
        Martin Odersky added a comment - It's an improvement in two ways: (1) There's no intermediate list that's built. (2) It works for more than 2 lists in exactly the same way.

          People

          • Assignee:
            Martin Odersky
            Reporter:
            Daniel Spiewak
            TracCC:
            Paul Phillips, Seth Tisue
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development