They are equivalent to set comprehension
Anatomy of a list comprehension:
[ output function | input set, predicate ]
Some examples
all the numbers from 1 to 10 doubled (notice the output function).
[x*2 | x <- [1..10]]
All the numbers from 1 to 10 doubled greater than 12.
[x*2 | x <- [1..10], x*2 >= 12]
all the numbers from 50 to 100 which the rest of x/7 = 3.
[ x | x <- [50..100], x `mod` 7 == 3]
The result of this is an array of length 3x3 (9)
[ x*y | x <- [2,5,10], y <- [8,10,11]]
Some fun.
ghci> let nouns = ["hobo","frog","pope"]
ghci> let adjectives = ["lazy","grouchy","scheming"]
ghci> [adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]
["lazy hobo","lazy frog","lazy pope","grouchy hobo","grouchy frog",
"grouchy pope","scheming hobo","scheming frog","scheming pope"]
Lazy Vs. Non-strict evaluation source
Non-strict languages do reduction (mathematical term for evaluation) from the outside in. This means if we have (a+(b*c))
then first you reduce the +
and then the (b*c)
. Strict languages work the other way around, thy would go all the way to the bottom outwards.
Lazy evaluation means that the program will only evaluate an expression when its results are needed.