3

Haskell newbie here. It is my observation that:

  • zip and zip3 are important functions - the are included in the Prelude, implemented by many other languages, represent a common operation in mathematics(transposition)

  • not generic with respect to parameter structure

  • easy to implement in traditional languages - C or C++ (say 20 hours work); python already has it as a build-in

Why is zip so restricted? Is there an abstraction, generalizing it? Something wrong with n-sized tuples?

Vorac
  • 8,726
  • 11
  • 58
  • 101
  • https://stackoverflow.com/questions/2468226/how-to-zip-multiple-lists-in-haskell https://stackoverflow.com/questions/39991581/how-can-i-implement-generalized-zipn-and-unzipn-in-haskell https://stackoverflow.com/questions/40342060/convert-a-tuple-of-lists-of-the-same-length-to-a-list-of-tuples-for-arbitrary – Josh Lee Apr 20 '17 at 13:21
  • https://stackoverflow.com/questions/7828072/how-does-haskell-printf-work – Josh Lee Apr 20 '17 at 13:25
  • @JoshLee thanks for the links. The seconds one gets the closest, but sill leaves me with a lot of qualms 1) why is the standard implementation for fixed n = 2 2) I need to pass the number of lists, that's unwieldy 3) even if I define my own zip, there will be collisions with Prelude.zip. – Vorac Apr 20 '17 at 13:26
  • 2
    "I need to pass the number of lists," then you need something other than `zip`. Even the more "generic" variants still need fixed numbers of arguments; I get the impression what you want is closer to the `transpose` function. – Cubic Apr 20 '17 at 13:52

2 Answers2

7

Because the suggested duplicates answer most of this, I will focus on the questions in your followup comment.

1) why is the standard implementation for fixed n = 2

zipWith is for 2 arguments, and repeat is for 0 arguments. This is enough to get arbitrary-arity zips. For example, the 1 argument version (also called map) can be implemented as

map f = zipWith ($) (repeat f)

and the 3 argument version as

zipWith3 f = (.) (zipWith ($)) . zipWith f

and so on. There is a pretty pattern to the implementations of larger zips (admittedly not obvious from this small sample size). This result is analogous to the one in CT which says that any category with 0-ary and 2-ary products has all finitary products.

The other half of the answer, I suppose, is that type-level numbers (which are the most frequent implementation technique for arbitrary-arity zips) are possible but annoying to use, and avoiding them tends to reduce both term- and type-level noise.

2) I need to pass the number of lists, that's unwieldy

Use ZipList. You don't need to pass the number of lists (though you do need to write one infix operator per list -- a very light requirement, I think, as even in Python you need a comma between each list).

Empirically: I have not found arbitrary-arity zips such a common need that I would label it "unwieldy".

3) even if I define my own zip, there will be collisions with Prelude.zip.

So pick another name...?

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
1

Because the type signatures would be different, for example the type signatures of zip and zip3 are different:

zip :: [a] -> [b] ->[(a,b)]

zip3:: [a] -> [b] -> [c] -> [(a,b,c)]

zip3 takes one more argument than zip and secondly the type, and haskell does not allow you to have a polymorphism with different numbers of arguments because of currying. Here is an explanation of what currying is on SO.

Community
  • 1
  • 1
TanasaIoan
  • 19
  • 1
  • 7