
Excerpts from Brent Yorgey's message of Wed Apr 29 23:41:03 -0400 2009:
Others' answers are probably more helpful for learning, but I also wanted to point out that there is a Prelude function that does something close to this (assuming you meant [4,5,6]), namely, 'sequence'.
Prelude> sequence [ [1,2,3], [4,5,6] ] [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]] Prelude> sequence [ [1,2], [3,4,5], [6,7] ]
[[1,3,6],[1,3,7],[1,4,6],[1,4,7],[1,5,6],[1,5,7],[2,3,6],[2,3,7],[2,4,6],[2,4,7] ,[2,5,6],[2,5,7]]
However, explaining how/why sequence does this requires understanding the list monad, which you may or may not want to tackle at this point.
Interesting! According to Hoogle, the sequence function evaluates each monad and then collects the results. I know evaluating a list monad returns a list, but what do they mean by "collect"?
If you import 'Control.Applicative' you can even do exactly what you wanted, with pairs and all:
Prelude Control.Applicative> liftA2 (,) [1,2,3] [4,5,6] [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
Here, liftA2 is applying the function (,) to every possible pair of values from the two lists.
I'm not even going to try to understand that now. Cheers, Edward