Haskell Ranges and List Comprehensions
Course Title: Functional Programming with Haskell: From Fundamentals to Advanced Concepts
Section Title: Lists, Ranges, and Infinite Data Structures
Topic: Using ranges and list comprehensions
In this topic, we will explore the concepts of ranges and list comprehensions in Haskell, which are used to construct and manipulate lists in a concise and expressive manner.
1. Ranges in Haskell
Ranges in Haskell are used to create lists of numbers within a specified range. They are defined using the ..
operator.
Example 1: Basic Range
ghci> [1..5]
[1, 2, 3, 4, 5]
In the above example, [1..5]
creates a list of numbers from 1
to 5
.
Example 2: Range with Step
ghci> [1,3..9]
[1, 3, 5, 7, 9]
In the above example, [1,3..9]
creates a list of numbers from 1
to 9
with a step of 2
.
You can also use the upto
function, which is a part of the List
module in Haskell, to create a range.
Example 3: Using upto
Function
ghci> [1..10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
However, the upto
function only takes two arguments. It will create a list of numbers from the first argument up to but not including the second argument.
ghci> [1..10] == [1 `upto` 10]
True
ghci> [1..10] == [1 `upto` 11]
True
2. List Comprehensions in Haskell
List comprehensions in Haskell are a way of creating new lists based on existing lists or other iterables. They consist of three parts: the output, the input set, and the set of conditions.
The general syntax of a list comprehension in Haskell is given by:
[expression | generator, predicate, ... generator, predicate]
In this syntax:
expression
is the value to be produced for each element in the output list.generator
specifies the data from which the elements will be selected.predicate
is the condition that determines whether the generated value should be included in the output list.
Let's see an example of a simple list comprehension.
Example 4: Basic List Comprehension
ghci> [x*y | x <- [1..5], y <- [1..5], x == y]
[1, 4, 9, 16, 25]
Here x*y
is the expression that gets evaluated for each combination of x
and y
. The list comprehension then collects the values of x*x
.
Example 5: A More Complex List Comprehension
ghci> [sum[x,y] | x <- [1..10], y <- [1..10], odd x, odd y]
[ 2, 4, 6, 8, ..., 200]
In this example, we iterate through all pairs of values between 1
and 10
and for those pairs for which x
and y
are both odd numbers, we include their sum in the resulting list.
Here's a list comprehension with an empty condition set. When that happens, all the possible values from the given range are included:
ghci> [x*y | x <- [1..5], y <- [1..5]]
[1, 2, 3, 4, 5, 2, 4, 6, 8, 10, 3, 6, 9, 12, 15, 4, 8, 12, 16, 20, 5, 10, 15, 20, 25]
This is different to simply combining the lists with the ++
function or using ++
with repeat
, or using ++
with map
. For more and detailed information, view this document: <https://orduring.github.io/posts/operador-de-rango-en-haskell/>
Now, let's summarize the topic by stating key concepts:
- Key Points:
- Ranges and list comprehensions are powerful methods for generating lists.
- The
..
operator can be used to specify a range. - The
upto
function is available as part of theList
module and it covers a half-open interval. - List comprehensions create new lists from existing iterables.
- They select data using generator and optional predicates.
Practical Takeaway: We have covered the topic of ranges and list comprehensions in Haskell which helps creating lists in different patterns from existing lists and ranges.
Please leave a comment or ask for help if you have any questions or need further clarification.
Let's move on to our next topic: Lazy evaluation and infinite lists
Images

Comments