Lists and Comprehensions
Welcome back to the next post now we will be learning about List and comprehensions, they form a large part of a typical Haskell program, so lets find out more about them now.
The List
|
|
Haskell loves lists! Due to the Type System, all list can only contain elements of the same type.
Haskell also allows for infinite lists. An example of this can be seen below, I have extended the definition above to include all the even numbers - cool right! However, when we use infinite lists we have to ensure that we write robust code, so that we know our programs will eventually terminate. This will become even more important when we talk about recursion.
|
|
## Basic List Operations Now we know about the list, lets look into some basic functions that can be applied to a list. This list shows us some of the most common functions, that are typically used with a List Comprehension
product
- returns the product of all the numbers in a listsum
- returns the sum of all the numbers in a listand
- applied a logic ‘and’ to the values in a list and returns the resultor
- applied a logic ‘or’ to the values in a list and returns the result!!
- the infix direct access operator, returns the element at the nth position of the list- Plus a lot more. Check out Hoogle, for a list of functions.
Now lets see some examples of how these functions are used.
product [1,2,3,4,5]
will return the value of 1*2*3*4*5
which is 120
.
sum [1,2,3,4,5]
will return the value of 1+2+3+4+5
which is 15
.
and [True,True,False,False,True]
will return the value of True && True && False && False && True
which is False
. Since there exists a False
within the list.
or [True,True,False,False,True]
will return the value of True || True || False || False || True
which is True
. Since there exist a True
within the list.
[0,2..100] !! 10
will return the element of the list [0,2..10]
that is in the 10th position. Warning , remember that list in Haskell and most programming languages are Zero Indexed, we start counting from zero not one.
List Comprehensions
Now we have the background knowledge its time we learn some List Comprehensions
I like to think of a list comprehension in exactly the same way I think about Set Notation from mathematics. I’m going to show the various part that make up a list comprehension.
|
|
The above may look complicated but that is more of the formal introduction to List Comprehensions.
Examples
Now lets run through some examples. I may introduce some more exciting functions as we go along. I will also take you through my thought process as I come up with a solution.
- Create a list comprehension that gives us all of the positive even numbers.
- So the answer needs to choose only the even numbers, so we will be needing a guard for even numbers. We will have to use the
even
function.- Lets find out more info about the even function.
- Open
ghci
as you have done previously - Enter
:info even
this can also be shortened to:i even
. - Take note of the type, we give it an
Integral
which is either aInt
orInteger
and it returns aBool
- This is exactly what we want, so lets use this handy function.
- We want all of the positive even numbers so we are going to have to use an infinite list. This is the generator.
- We don’t need to apply any function to the number that is added from the generator.
- So the final List Comprehension becomes the one below.
- So the answer needs to choose only the even numbers, so we will be needing a guard for even numbers. We will have to use the
|
|
- Create a list of the first 100 perfect squares.
- When creating this list we can either, check if a number is a perfect square using a guard then add it, or create the perfect squares ourselves. I personally think the latter is easier.
- So we won’t be needing any guards for this solution.
- The generator should give us all of the first 100 integers so that we can make them into the perfect squares.
- We will need to apply a functions to each of the values, we need to square them.
- So the final List Comprehension becomes the one below.
|
|
- Find the product of the first 100 perfect squares
- This problem would be very complicated to solve without the aid of a computer.
- We will be composing a previous solution with one of the list functions we introduced earlier in this post.
- We already have list of the first 100 perfect squares, now we need to get the product of all of them.
- Lets get more info about the
product
function- Lets open
ghci
- Enter
:i product
- Note the function takes a list of numbers and returns a single number
- This is exactly what we want, lets use the product function
- Lets open
- So the final List Comprehension becomes the one below.
|
|
- Define a function that takes a
String
argument and returns aString
containing only the letters of the input but now all lowercase.- From one of my previous post I said a
String
is a Type Alias for[Char]
. We are going to have to use this fact to answer this question. - We have to only add characters that are letters so we are going to have to use a guard. Lets find out more info about the
isLetter
function.- As previously use
ghci
to get more information about the function - We can see that the function takes a
Char
and returns aBool
this is perfect for what we want - We are given a string so that must form part of the generator
- Finally we must make all of the characters lowercase, so we must apply a function to each of them. Lets look at the
toLower
function- Again use
ghci
to get more info - We see that the function takes a
Char
and returns aChar
this is what we want - So the final list comprehension becomes
- Again use
- As previously use
- From one of my previous post I said a
|
|
The above is a more complex example, lets go through the main parts of it again for clarity.
For this problem we have defined a function f
that takes a String
as input and returns a String
.
The input string is the xs
on the left hand side of the assignment operator =
.
We go through each element of xs
which has type [Char]
, we call this element x
.
First we check if it is a letter, if False
it is discarded, if True
we apply the toLower
function, making it lowercase then add it to the list to be returned.
Conclusion
I hope this post has been beneficial. There are many situations in which list comprehension can massively simplify problems that you will face so always keep them in mind. In the next post I will be covering Lists and Recursion. Kyle out!