On Sun, Mar 9, 2008 at 7:27 PM, Philip Müller <
mail@philip.in-aachen.net> wrote:
Hi,
I'm just working through Hutton's "Programming in Haskell" and I found
an exercise which I can't solve, although it looks simple. Maybe someone
here could give me a hint?
Exercise:
Show how the single comprehension [(x,y) | x <- [1,2,3], y <- [4,5,6]]
with two generators can be re-expressed using two comprehensions with
single generators.
Hint: make use of the library function _concat_.
Another hint, list comprehensions are just values of type [ a ] (a would be Integer in this case). So in other words, in any place where you want a list, you can stick a list comprehension. In this case you want to take each x in xs, and then for each x you want to grab each y in ys, and return (x,y). Right, so we know how to do that first bit, the "for each x in xs" bit, right? Just do [ ... | x <- xs ]. And now what do we want to do for each element of x? Well we want to do "for each y in ys", right? So that's just another list comprehension [ ... | y <- ys ].
Stick the two together and you get [ [ ... | y <- ys] | x <- xs ]. So what do we want to do to x and y? Well we want to pair them: [ [ (x,y) | y <- ys] | x <- xs ]. Now, this gives us a list of lists (because each element of x will yield a list of x,y pairs, where x is constant and y is each element in ys). To flatten this into a single list, you can use concat:
concat [[ (x,y) | y <- ys] | x <- xs ]