1

So lets say I want a function foo, that takes as argument, any number of lists, and return every combinations of the lists elements.

So for instance, foo [0,1] [0,1,2] would return [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]

and foo [0,1] [0,1] [0,1] would return [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[1,1,0],[1,0,1]]

I was thinking of working recursively, and for the second example for instance, having foo x y = [[a,b]|a <- x, b <- y], and essentially call foo (foo [1,0] [1,0]) [0,1]

But the problem i have right now is that foo returns a list of a list, so the more arguments i give it, the more nested lists it will have and the recursive calls won't work. Does anyone have any idea on how i can approach such a function?

I think working with foo x y is a good idea, so that i can recursively call it on any number of lists. So if i had ls = [[0,1],[0,1],[0,1,2],[0,1,2,3],[0,1,2,3,4]] I would call foo on the first two and then on the next one and so on.

Rodrigo de Azevedo
  • 1,097
  • 9
  • 17
Unknown
  • 21
  • 1
  • 1
    The accepted answer on the dupe doesn't answer this question, but many of the dupe's other answers touch on cartesian products of n>2 lists. – Adam Smith Apr 11 '18 at 17:27

2 Answers2

3

if you wrap all your inputs in a list foo==sequence

e.g.

> sequence [[0,1], [0,1,2]]

[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]
karakfa
  • 66,216
  • 7
  • 41
  • 56
3

This is sequenceA or sequence. (The former uses [a]'s Applicative instance while the latter uses [a]'s Monad instance, but in this case they're identical). Both are defined in terms of traverse, but let's define it ourselves:

foo = foldr f (pure [])
  where
  f x ys = (:) <$> x <*> ys
Adam Smith
  • 52,157
  • 12
  • 73
  • 112