List in Haskell

Much like shopping lists in the real world, lists in Haskell are very useful. List stores multiple homogeneous items in an index-based way.

List not only helps to store the items in it but also it helps the user to perform multiple operations on it. In Haskell, lists are a homogeneous data structure. It stores several elements of the same type. That means that we can have a list of integers or a list of characters but we can't have a list that has a few integers and then a few characters. And now, a list!

We can use the let keyword to define a name right in GHCI. Doing let a = 1 inside GHCI is the equivalent of writing a = 1 in a script and then loading it.

ghci> let numberList = [1, 4, 6, 7]
ghci> numberList
[1, 4, 6, 7]

As you can see, lists are denoted by square brackets and the values in the lists are separated by commas. If we tried a list like [1,2,'a',3,'b','c',4], Haskell would show an error that characters (which are, by the way, denoted as a character between single quotes) are not numbers.

Speaking of characters, strings are just lists of characters. "Haskell" is just syntactic sugar for ['h','a','s','k','e', 'l', 'l']. Because strings are lists, we can use list functions on them, which is really handy.

Operations on List

Let's learn about operations performed on the lists in Haskell

Append two lists :

In Haskell, we can append two lists using the ++ operators.

ghci> [1,2,3,4] ++ [5,6,7,8]
[1,2,3,4,5,6,7,8]

consing :

In addition to specifying the whole list at once using square brackets and commas, you can build them up piece by piece using the (:) operator pronounced "cons".

The process of building up a list this way is often referred to as consing.

We can also add a list and an individual element to the list to the first place using : operator in Haskell, : will be very useful when you have a huge list.

ghci> 0:[1,2,3,4,5]
[0,1,2,3,4,5]

// below will not work
ghci> [1,2,3,4,5]  : 7

Index !! in Haskell lists

It is important to get an element based on the index of the element in the list, haskell provides !!(index) operator to get a value from a particular index. In haskell the index starts with 0;

ghci> "karthiQ" !! 5
'i'
ghci> [1, 2, 3, 4, 5] !! 1
2

From the below image you can understand how the list is stored.
list-in-haskell

If you try to access the 6th element when only is there then Haskell will throw an error
*** Exception: Prelude.!!: index too large

Lists of lists

Lists can contain anything — as long as they are all of the same types. Because lists are things too, lists can contain other lists!

Example for list of lists in Haskell:

Lists can contain lists
ghci> let listOfLists = [[1,2],[3,4],[5,6]]
ghci> listOfLists
[[1,2],[3,4],[5,6]]

We can access a list of lists using the !! index operator

ghci> listOfLists !! 2
[5,6]

We also can access the elements present in the list of lists using the index operators.

ghci> listOfLists !! 2 !! 1
6

The lists within a list can be of different lengths but they can't be of different types. Just like you can't have a list that has some characters and some numbers, you can't have a list that has some lists of characters and some lists of numbers.

Functions in Haskell list

The head takes a list and returns its head, The head of a list is basically its first element.

ghci> head [1,3,5,6]
1

If you have the list in a variable then the head will bring the first element but it has no effect on the list. So the original list stays the same.

ghci> let li =[2,3,4,5]
ghci> head li
2
ghci>
ghci> li
[2,3,4,5]
ghci>

tail

The tail takes a list and returns its tail, In other words, the tail removes the first element from the list and returns the remaining list. But it does not have any effect on the original list.

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> tail li
[3,4,5]
ghci> li
[2,3,4,5]
ghci>

last

last takes a list and returns its last element. It has no effect on the original list

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> last li
5

init

init takes a list and returns list without the last element of the list, has no effect on the original list

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> init li
[2,3,4]
ghci>

length

The length takes a list and returns its length, length is the number of elements present in the list. The last index is always length-1 as list index starts from 0

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> length li
4
ghci>

null

null checks if a list is empty. If it is, it returns True, otherwise, it returns False. This will be useful when you are not sure whether a list has some elements or not.

ghci> null [1,2,3]
False
ghci> null []
True

reverse

reverse reverses the given list of items.

ghci> reverse [5,4,3,2,1]
[1,2,3,4,5]

take

take takes a number and a list. It extracts that many elements from the beginning of the list.

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> drop 2 li
[4,5]
ghci> li
[2,3,4,5]
ghci> take 3 li
[2,3,4]
ghci> li
[2,3,4,5]
ghci>

drop

drop works in a similar way, only it drops the number of elements from the beginning of a list.

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> drop 2 li
[4,5]
ghci> li
[2,3,4,5]
ghci>

elem

elem takes a thing and a list of things and tells us if that thing is an element of the list. It's usually called an infix function because it's easier to read that way. elem should be used along with the ` and it is not a single quote

ghci> 4 `elem` li
True
ghci>

Mathematical function on the list

maximum and minimum

The maximum takes a list of stuff that can be put in some kind of order and returns the biggest element. minimum returns the smallest element in that list

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> maximum li
5
ghci> minimum li
2
ghci>

sum

sum takes a list of numbers and returns their sum.

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> sum li
14

product

The product takes a list of numbers and returns their product.

ghci> let li =[2,3,4,5]
ghci> li
[2,3,4,5]
ghci> product li
120
ghci>

Ranges with Lists in Haskell

Range (..

Haskell is able to generate the number based on the given range, range is nothing but an interval between two numbers.

Haskell generates the ranges based on the given function. Ranges are generated using the.. operator in Haskell.

To make a list containing all the natural numbers from 1 to 20, you just write [1..10]. That is the equivalent of writing [1,2,3,4,5,6,7,8,9,10] and there's no difference between writing one or the other except that writing out long enumeration sequences manually is stupid.

ghci> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
ghci> ['a'..'z']
"abcdefghijklmnopqrstuvwxyz"
ghci> ['K'..'Z']

cycle

The cycle takes a list and cycles it into an infinite list. If you just try to display the result, it will go on forever so you have to slice it off somewhere.

ghci> take 7 (cycle [0,2,4])
[0,2,4,0,2,4,0]
ghci>

repeat

repeat takes an element and produces an infinite list of just that element. It's like cycling a list with only one element.

ghci> take 3 (repeat 7)
[7,7,7]
ghci>

replicate

replicate function create a given number of the same element in a list.

ghci> replicate 10 7
[7,7,7,7,7,7,7,7,7,7]
ghci>
About Author :

I am Pavankumar, Having 8.5 years of experience currently working in Video/Live Analytics project.

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions