Lecture 6-2
List Comprehensions
List ranges can produce simple arithmetic sequences but list comprehensions can produce more complex lists:
> [x*x | x <- [1..10]]
> [1,4,9,16,25,36,49,64,81,100]
By using this you can apply a function to a list and put the result into a list.
Predicates
Predicates also add evaluations into the list to limit the results.
> [x*x | x <- 1..10, x*x > 40]
> [49,64,81,100]
This limited the output of the previous example to be strictly greater than 40.
Multiple predicates can be separated by multiple commas:
> [x*x | x <- 1..10, x*x > 40, x*x < 80]
> [49,64]
In Functions
The body of a function can be a list comprehension:
-- This function will print the even values less than a supplied value.
evens_less_than y = [x | x <- [0..(y - 1)], x `mod` 2 == 0]
To test each value in a list the following can be applied:
-- This function will step through each value in the list `xs`
-- and apply the function.
lts10 xs = [ if x < 10 then "Yes" else "No" | x <- xs]
Multiple Variables
You can also use more than one sublist in a list comprehension. This will step though every combination of the two lists and print the operation of the lists. This is similar to a nested for loop.
> [ x*y | x <- [2,5,10], y <- [8,10,11]]
> [16,20,22,40,50,55,80,100,110]
This can also be combined with predicates:
> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]
> [55,80,100,110]
Look at the slides for more examples of the topics above. This includes examples for some non-trivial functions such as: Factors of a Value, Prime Numbers up to a Value.
Lists of Lists
-
Lists can contain lists provided that they contain the same type. These lists don’t merge but each element in the main list is the sublists:
[[1,2,3,4],[1,2,3,4]]
-
Tuples can also be put in a list provided that they are the same type. This means that the tuples must be:
- Containing the same type.
- Of the same length.
[(1,2,3,4),(1,2,3,4)]
-
As a result of the lists containing a list the following happen:
> let x = [[1,2,3],[4],[5,6]] > head x > [1,2,3] > tail x > [[4],[5,6]] > length x > 3
-
As you can have lists of lists you can also nest list comprehensions in lists. An example of this is in the slides.
List Comprehensions in Other Languages
List comprehensions arose in the functional programming world but they have appeared in imperative languages.
For example in Python:
squares = [x**2 for x in range(10)]
[x.lower() for x in ["A","B","C"]]
Exercises
-
cubesupto x = [y * y * y | y <- [1..x]]
-
nospaces xs = [x | x <- xs, x /= ' ']
-
allpairs x y = [(a,b) | a <- [1..x], b <- [1..y]]