16 Mar 2013

As of March 2020, School of Haskell has been switched to read-only mode.

## Tuples and Lists

We have already encountered tuples prior, albeit very briefly. Now we will introduce them alongside their cousin, lists.

Tuples are hereogenous, meaning that their elements may be of different types.

``````aTuple = (1, 2, 34)
anotherTuple = (1, "two", (3, "four"))
main = print \$ (aTuple, anotherTuple)``````

The latter `anotherTuple` consists of an integer, a string, and even another tuple.

In fact the value passed tot he print statement is itself a tuple consisting of two tuples, both of which are of different constituent types.

Lists, on the other hand, are homogenous, menaing that all of their lements must be of the same type.

``````aList = [1, 2, 34]
anotherList = [1, "two", [3, "four"]]
main = print \$ (aList, anotherList)``````

This fails to evaluate, because all elements need to be the same.

``````aList = [1, 2, 34]
anotherList = ["one", "two", "thirty four"]
yetAnotherList = [(1, 1), (2, 3), (5, 8)]
main = print \$ (aList, anotherList, yetAnotherList)``````

Now this works, because all of the values within the lists are of the same type.

How do you tell a list apart from a tuple?

``````aListHasSquareBrackets = [1, 2, 3]
aTupleHasRoundParentheses = (1, 2, 3)``````

## List operations

Prepending an element to a list

``````anElement = (-22)
anotherElement = 2
aList = [1, 2, 34]
yetAnotherList = anElement:anotherElement:aList
main = print \$ (anElement, anotherElement, aList, yetAnotherList)``````

Prepending a list to another list

``````anotherList = [(-22), 2]
aList = [1, 2, 34]
yetAnotherList = aList ++ anotherList
main = print \$ (anotherList, aList, yetAnotherList)``````

String concatenation

``````aStr = "Hello"
bStr = " World!"
concatenatedStr = aStr ++ bStr
main = print \$ (aStr, bStr, concatenatedStr)``````

Turns out that strings are lists of characters: `[Char]` So strings can be concatenated the same way lists are, pretty cool, eh?

Accessing a list by index

``````anotherList = [(-22), 2]
aList = [1, 2, 34]
yetAnotherList = aList ++ anotherList
thirdElement = yetAnotherList !! 2
main = print \$ (yetAnotherList, thirdElement)``````

Note that, as with almost all other programming languages, indices start at zero.

Other miscellaneous functions - explore the following: `length`, `head`, `last`, `tail`, `init`,

``````m = [1..7]
--m = []

--x = length m
--x = tail m
--x = last m
--x = init m
--x = reverse m
--x = sum m
--x = product m
--x = minimum m
--x = null m
--x = maximum m

main = print \$ (x)``````

Remove the `--` one line at a time to uncomment. Be sure to try each function on both empty and non-empty lists.

Now it is time for an exercise!

Above, we have the function `maximum`. I want you to define your own function that accomplishes the exact same thing: return the element of the input list which is the largest. We shall call it `listMax`

``````listMax m

aList = [(-3)..2]
bList = [1,(-17),3,(-3),(-10),0]
main = do
print \$ listMax aList
print \$ listMax bList``````

Clues:

A clue to get you to the final answer:

Write a `minList` function, which is exactly the same as `maxList`, except that it finds the smallest element in a list.
Note that these implementations still leave a lot to be desired. If you so wish, take a look at Haskell's own implementation of `minimum` and `maximum`.