Skip to content

Haskell Lists Guide — List Operations, Ranges, and List Comprehensions

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Haskell Lists Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Haskell lists are immutable singly-linked lists where all elements have the same type -- supporting cons (:) and append (++) operators, ranges with .., and powerful operations like map, filter, fold, and list comprehensions for declarative data processing.

Creating Lists

-- Literal
nums = [1, 2, 3, 4, 5]
chars = ['a', 'b', 'c']

-- Range
oneToTen = [1..10]
evens = [2,4..20]
countdown = [10,9..1]
letters = ['a'..'z']

-- Cons and nil
list = 1 : 2 : 3 : []  -- same as [1,2,3]

Basic Operations

-- Head and tail
head [1,2,3]  -- 1
tail [1,2,3]  -- [2,3]

-- Init and last
init [1,2,3]  -- [1,2]
last [1,2,3]  -- 3

-- Length, null, reverse
length [1,2,3]  -- 3
null []         -- True
reverse [1,2,3] -- [3,2,1]

-- Element access
[1,2,3] !! 1    -- 2
take 2 [1,2,3] -- [1,2]
drop 2 [1,2,3] -- [3]

List Comprehensions

-- Basic comprehension
squares = [x^2 | x <- [1..10]]
-- [1,4,9,16,25,36,49,64,81,100]

-- With condition
evensSquared = [x^2 | x <- [1..10], even x]
-- [4,16,36,64,100]

-- Multiple generators
pairs = [(x,y) | x <- [1..3], y <- ['a','b']]
-- [(1,'a'),(1,'b'),(2,'a'),(2,'b'),(3,'a'),(3,'b')]

-- Nested conditions
result = [x | x <- [1..50], x `mod` 7 == 0, x > 20]
-- [21,28,35,42,49]

Common Functions

-- Map and filter
map (*2) [1..5]      -- [2,4,6,8,10]
filter even [1..10]  -- [2,4,6,8,10]

-- Fold (reduce)
foldl (+) 0 [1..5]  -- 15
foldr (+) 0 [1..5]  -- 15
sum [1..5]          -- 15
product [1..5]      -- 120

-- Zip
zip [1..3] ['a','b','c']  -- [(1,'a'),(2,'b'),(3,'c')]
zipWith (+) [1,2,3] [4,5,6]  -- [5,7,9]

Common Mistakes

1. Indexing with !!

!! is O(n), not O(1). For random access, use Data.Array or Data.Sequence.

2. Infinite lists without take

[1..] creates an infinite list. Always use with take, filter, or other terminating functions.

3. Using ++ on large lists

++ is O(n) on the left list. For building large lists, prepend with : and reverse at the end.

Practice Questions

1. How do you create a list from 1 to 10? [1..10] or [1,2..10] for a range. Step can be specified: [1,3..10].

2. What does head [] return? An error -- Prelude.head: empty list. Always check for non-empty before using head.

3. How do you filter even numbers? filter even [1..10] or [x | x <- [1..10], even x].

FAQ

{{< faq question="Are Haskell lists linked lists?" >}} Yes. Each list is a chain of cons cells. This makes prepending O(1) and indexing O(n). {{< /faq >}}

{{< faq question="What is the difference between foldl and foldr?" >}} foldl associates left (processes from left), foldr from right. foldr works on infinite lists. foldl causes stack overflow on large lists. {{< /faq >}}

{{< faq question="Can lists have different types?" >}} No, lists are homogeneous. For mixed types, use a tuple or a custom algebraic data type. {{< /faq >}}

What's Next

Now learn about Recursion in Haskell.

Topic Description Link
Recursion Recursive functions and patterns {{< ref "07-recursion" >}}
Higher-Order Functions Functions as values {{< ref "08-higher-order-functions" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro