Home > Net >  How to implement zipWith N in Haskell
How to implement zipWith N in Haskell

Time:07-23

In my code, zipWith7 works well but now the function in zipWith7 require extra arity .

zipWith8 (\a b c d e f g h-> ....) List-A  ... List-H

while haskell base library only support up to 7 arity version.

Is there a way that can expand the function to N likr zipWithN ?

CodePudding user response:

One simple way to do this (not that zipWith8 and friends are really commonly needed!) is to make use of the ZipList type and the Applicative operators.

zipWith8 f a b c d e f g h = getZipList $
  f <$> ZipList a
    <*> ZipList b
    <*> ZipList c
    <*> ZipList d
    <*> ZipList e
    <*> ZipList f
    <*> ZipList g
    <*> ZipList h

I'm sure you can figure out from this to write zipWith9 etc if you wanted to.

Aside: this is mentioned in the chapter of Learn You a Haskell dealing with Applicatives:

Aside from zipWith, the standard library has functions such as zipWith3, zipWith4, all the way up to 7. zipWith takes a function that takes two parameters and zips two lists with it. zipWith3 takes a function that takes three parameters and zips three lists with it, and so on. By using zip lists with an applicative style, we don't have to have a separate zip function for each number of lists that we want to zip together. We just use the applicative style to zip together an arbitrary amount of lists with a function, and that's pretty cool.

CodePudding user response:

You can zip the first two lists to reduce the arity by one, if you also uncurry the function:

zipWithNplus1 f xs1 xs2 xs3 ... xsNplus1 =
   zipWithN (uncurry f) (zip xs1 xs2) xs3 ... xsNplus1

Otherwise, enable ParallelListComp and write a parallel list comprehension of any arity:

[ f x1 ... xN
| x1 <- xs1
| x2 <- xs2
| x3 <- xs3
...
| xN <- xsN
]
  • Related