Q: Why is there no List.zip?

As I was doing a test case to be used with elm-test, I wanted to merge two lists into a list of tuples like this: [inputs] [expects] → [(input, expect),… ]
I assumed there’s an Elm command so as in Python like List.zip but there is only List.unzip
: List ( a, b ) → ( List a, List b )

That is just the reverse of List.zip
So I have made it my self this way:

module Zip exposing (zip)

zip: List a → List b → List (a, b)
zip a b =
List.map2 (\x y → (x, y)) a b

It seems to work.

import Zip exposing (zip)
aList = [1,2,3]
bList = [4,5,6]
zip aList bList

[(1, 4), (2, 5), (3, 6)]

Is there somewhere another, better way to do the same?

You found its definition, it’s pretty simple so there isn’t really a better way to do it.
You could define zip as follows

zip = List.map2 Tuple.pair

But that’s just the partially applied version of what you already defined so both are equivalent*

*there might be slight performance differences between the fully applied and partially applied versions.

1 Like

For many things that are missing from the core libraries, they are provided in the “extra” libraries in the elm-community organization. In this case, List.Extra has zip.

3 Likes

All good answers to the original question.

I believe (but don’t know) that the non-inclusion of zip in the core List module is not an oversight, it’s a deliberate choice. In general the standard library is somewhat sparse for the base types. This is to discourage using the base types in favour of more tailoured types.

List processing in functional languages is pretty convenient, however, lists are not always the best choice of data structure, and it’s (perceived to be) a problem that code in functional languages can become a bit “listly typed”, the equivalent of stringly typed. So making it a modicum less convenient to default to using lists everywhere it is hoped that Elm developers are ultimately better off.

In your case it may of course be that a list of tuples is the exactly correct choice, but hopefully the fact that you had to come here to ask has at least made you consider alternatives. In particular ask yourself whether the tuple is the correct choice here. What do you then do with the tuple? Might it be better as a record type? That is almost as convenient as you can use List.map2 <record constructor>. Perhaps you are using the list of tuples as an ‘association list’ in which case consider a dictionary. An association list can have multiple values for the same key, a dictionary cannot, which do you need? If the list/dictionary will contain only a handful items perhaps the association list is the best choice, but hopefully the fact that List.zip doesn’t exist in the core at least makes you stop to consider these alternatives.

I can speak for myself and say that there have been many occasions on which the lack of a simple function in the standard library has caused me to re-think my data structure.

7 Likes