New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of #zipWith Method to Standard Collections #1512

Closed
scabug opened this Issue Nov 14, 2008 · 12 comments

Comments

Projects
None yet
2 participants
@scabug
Copy link

scabug commented Nov 14, 2008

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.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 14, 2008

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 14, 2008

@DRMacIver said:
There's generally a shortage of a lot of good higher order methods that are present in Haskell and could quite reasonably be generically present on some of the scala collection interfaces (many things in Data.List could go on scala's Iterable. A lot of map functionality. etc.)

Maybe we can try to get a bunch of them in as part of the collections upgrade?

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 14, 2008

@odersky said:
zipWith will be part of 2.8 collections. I'll post a first strawman proposal of the API soon. I'd be happy to have others contribute and flesh out bits and pieces of this.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 14, 2008

@DRMacIver said:
That sounds great. I'm very happy to do whatever I can to help with the new collections.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 18, 2008

Anders Bach Nielsen [X] (nielsen) said:
As Martin said, this will be included in the collections library update for 2.8.0

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Aug 15, 2009

@paulp said:
It is difficult to understand the reasoning behind closing a ticket like this with no actual implementation. There is as yet no zipWith in the new collections.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 16, 2009

@odersky said:
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)
@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 16, 2009

@SethTisue said:
beware #2634, though

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 16, 2009

@djspiewak said:
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.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 16, 2009

@SethTisue said:
djspiewak: that doesn't compile.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 16, 2009

@djspiewak said:
Oh yeah. Obviously... :-)

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Nov 16, 2009

@odersky said:
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment