How to work on lists
How do I…?[edit]
Given any list xs
, how do I...?
Basics[edit]
- Get the size of the list.
length xs
- Turn a list backwards.
reverse xs
Finding / searching[edit]
- Get the Nth element out of a list.
xs !! n
- Indexes are zero based, so
[1,2,3] !! 0
will result in1
. - (Related:
head xs
returns the first element of the list.) - (Related:
last xs
returns the last element of the list.)
- Get a list of all elements that match some condition.
filter my_test xs
- (Returns everything that passes the test.)
- Find the highest/lowest element of a list.
minimum xs
maximum xs
- (Works not just for numbers but anything that is a member of the
Ord
class. In particular, that includes characters and strings.)
Adding[edit]
- Add an element to the start of a list.
new_element : xs
- Add an element to the end of a list.
xs ++ [new_element]
- Insert an element into the middle of a list.
- Generally, you will have to split the list into two smaller lists, put the new element to in the middle, and then join everything back together. For example:
let (ys,zs) = splitAt n xs in ys ++ [new_element] ++ zs
- Join two lists together.
list1 ++ list2
Deleting[edit]
- Delete the first N elements from a list.
drop n xs
- (Related:
tail xs
removes just one element.) - (Related:
init xs
removes just the last element.)
- Make a new list containing just the first N elements from an existing list.
take n xs
- Split a list into two smaller lists (at the Nth position).
splitAt n xs
- (Returns a tuple of two lists.)
- Delete the just Nth element of a list.
- This is tricky. AFAIK, there is no built-in function that does this. You have to split the list in two, remove the element from one list, and then join them back together, like this:
let (ys,zs) = splitAt n xs in ys ++ (tail zs)
- (Related:
tail xs
removes the first element.) - (Related:
init xs
removes the last element. Slow if the list is big.)
- Delete elements that meet some condition.
- Haskell has a function called
filter
which will do this for you. Beware though: it should really be named 'select' instead. For example,filter odd xs
returns a list of odd numbers. That is, it deletes everything that is not odd.
Testing various conditions[edit]
- Check if a list is empty.
null xs
- Find out whether any list element passes a given test.
any my_test xs
- Check whether all list elements pass a given test.
all my_test xs
Modifying the list or its elements[edit]
- Apply a function to all list elements.
map my_function xs
- Apply a function to just some elements of a list.
- Assuming you only want to apply function
f
to elements for which functionp
returns true, you can do this: map (\x -> if p x then f x else x) xs
- Convert a list of foos into a list of bars.
- Find or write a function to convert foo into bar, and then apply it to the whole list using
map
.
- Number the elements of a list (so I can process each one differently according to its position).
zip xs [0..]
- (For example,
zip ['a','b','c'] [0..]
gives[('a',0),('b',1),('c',2)]
.)
- Apply a list of functions to a single element to get a list of results.
- It's not in the book, but it's easy when you know how:
map ($ my_element) xs
- Total up a list of numbers.
sum xs
- (Related:
product xs
will multiply all the elements together instead of adding them.)
- Sort a list.
- You'll need to import
Data.List
first, but then you can just dosort xs
.
- Find out if some item is in a list.
my_element `elem` xs
Lists and IO[edit]
- Execute a list of IO actions.
- Turn a list of IO actions into one IO action that returns a list of results:
sequence xs
Prelude> sequence [putStr "hello ", putStrLn "world"]
hello world
[(),()]
- (Note: you might want to use
sequence_
instead, like in the above case, if your actions only return()
)
- Execute an IO action on each element of a list.
- You could map the IO function over your list (resulting in a list of actions) and then perform them using the trick above. But it's much simpler to do this:
mapM my_action xs
- or
mapM_ my_action xs
- where
mapM f xs = sequence (map f xs)
and similarly forsequence_
.
Notes about speed[edit]
Haskell lists are ordinary single-linked lists. (Look up the term in any book on data structures.) This gives them certain speed properties which are well worth knowing.
Fast operations[edit]
The following operations are always 'fast':
- Prepend 1 element (the
:
operator) head
(get first element)tail
(remove first element)
Slower operations[edit]
Any function that does something with the Nth element or the first N elements generally gets slower as N increases. The following all slow down as n
gets larger:
xs !! n
take n xs
drop n xs
splitAt n xs
Any function which needs to process the entire list obviously gets slower as the list gets bigger. The following all slow down as the list xs
gets larger:
length xs
list1 ++ list2
(speed depends only on the size oflist1
)last xs
map my_fn xs
filter my_test xs
zip my_fn list1 list2
(speed depends on the smallest of the two lists - as does the size of the result list!)x `elem` xs
sum xs
minimum xs
maximum xs
GHC Data.List
functions [edit]
Data.List
functionsThe Data.List
module has many functions for sorting, modifying and building lists.