[(x, y) | x <- ['a'..'z'], y <- ['A'..'Z']]
Is there any way to get this result:
[(a,A), (b, B), ..]
and not this:
[(a, A), (a, B), ..]
without using any plus function ?
>Solution :
Yes, the right way is to zip the two lists: zip ['a'..'z'] ['A'..'Z'], but if you use ZipLists you can achieve the same with applicative style:
import Control.Applicative (ZipList)
getZipList $ (,) <$> (ZipList ['a'..'z']) <*> (ZipList ['A'..'Z'])
[('a','A'),('b','B'), {- the list you wanted -}]
(Look at LYAH for more details.)
Compare the above with the following
(,) <$> ['a'..'z'] <*> ['A'..'Z']
which is equivalent to your list comprehension.
We are basically applying the same pattern to "zip lists" which are simply like "normal lists" but with a different dressing.
Unfortunately (and I did not know), the list comprehension is truly a "normal list" comprehension, so it does not desugar to the applicative style above, which means that
[(x, y) | x <- (ZipList ['a'..'z']), y <- (ZipList ['A'..'Z'])]
is not valid Haskell.