> For example, the following zips together two lists:
[ (x, y) | x <- xs | y <- ys ]
For clarity, here's your normal list comprehension (with one pipe) that produces all the combinations instead:
[ (x, y) | x <- xs, y <- ys ]
{-# LANGUAGE ParallelListComp #-} import Control.Monad (mapM) elems = [ "water", "earth", "fire", "air" ] nats = [ "tribes", "kingdom", "nation", "nomads" ] main = mapM putStrLn [ show idx ++ " - " ++ e ++ " " ++ n | e <- elems | n <- nats | idx <- [0..] ]
main = forM (zip3 elems nats [0..]) $ \(e, n, idx) -> putStrLn (show idx ++ " - " ++ e ++ " " ++ n)
main = mapM putStrLn $ do (e, n, idx) <- zip3 elems nats [0..] [ show idx ++ " - " ++ e ++ " " ++ n ]
> For example, the following zips together two lists:
That's precisely the difference between a normal list comprehension (one pipe) and a parallel list comprehension (multiple pipes).For clarity, here's your normal list comprehension (with one pipe) that produces all the combinations instead:
And here's the full example from the article converted to Haskell and producing the exact same output: EDIT: I suppose an explicit zip with an anonymous function looks more idiomatic though: EDIT2: Best of both worlds with the list monad?