# "listProduct" -- is this a standard function?

Graham Klyne gk at ninebynine.org
Wed Oct 15 18:07:00 EDT 2003

```I've constructed a "listProduct" function that I think I've seen somewhere
else... is it a standard function?  If so, where is it defined?

My code is:
[[
-- |Given a list of lists, construct a new list of lists where
--  each member of the new list is the same length as the original
--  list, and each member corresponds to a different choice of
--  one element from each of the original members in the
--  corresponding position.  Thus:
--
--  listProduct [[a1,a2],[b1],[c1,c2]] =
--       [ [a1,b1,c1], [a1,b1,c2], [a2,b1,c1], [a2,b1,c2] ]
--
--  Note:  The length of the resulting list is the product of
--  lengths of the components of the original list.  Thus, if
--  any member of the original list is empty then so is the
--  resulting list:
--
--  listProduct [[a1,a2],[],[c1,c2]] = []
--
listProduct :: [[a]] -> [[a]]
listProduct []       = [[]]
listProduct (as:ass) = concat [ map (a:) (listProduct ass) | a <- as ]

test1 = listProduct [["a1","a2"],["b1"],["c1","c2"]]
test2 = listProduct [["a1","a2"],[],["c1","c2"]]
]]

And a supplementary point.  Following a comment made to me previously, I
can replace this list comprehension (not having any guard expressions) with
another map function, thus:

[[
lp []       = [[]]
lp (as:ass) = concatMap (\a -> (map (a:) (lp ass))) as
]]

I think I should also be able to eliminate the lambda-abstraction, but I
can't see how.  I prefer the list comprehension, as I find that easier to