From Wikibooks, open books for an open world
< Haskell | Solutions
This page may need to be
reviewed for quality.
← Back to Lists and tuples
[edit] Building lists
| Exercises |
- Would the following piece of Haskell work:
3:[True,False]? Why or why not?
- Write a function
cons8 that takes a list and conses 8 on to it. Test it out on the following lists by doing:
cons8 []
cons8 [1,2,3]
cons8 [True,False]
let foo = cons8 [1,2,3]
cons8 foo
- Write a function that takes two arguments, a list and a thing, and conses the thing onto the list. You should start out with:
let myCons list thing = |
- This won't work. [True, False] is a list of booleans, 3 is an integer.
let cons8 list = 8:list, let cons8 = (:) 8 and let cons8 list = (:) 8 list are all valid functions.
cons8 [] returns [8]
cons8 [1,2,3] returns [8,1,2,3]
cons8 [True,False] gives a type error. This is the same mistake as in exercise 1.
let foo = cons8 [1,2,3] gives no output message, but foo is [8,1,2,3]. Try it!
cons8 foo (assuming you did 2.4) returns [8,8,1,2,3]
let myCons list thing = thing : list, let myCons list thing = (:) thing list are both valid functions.
[edit] Lists within lists
| Exercises |
- Which of these are valid Haskell and which are not? Rewrite in cons notation.
[1,2,3,[]]
[1,[2,3],4]
[[1,2,3],[]]
- Which of these are valid Haskell, and which are not? Rewrite in comma and bracket notation.
[]:[[1,2,3],[4,5,6]]
[]:[]
[]:[]:[]
[1]:[]:[]
["hi"]:[1]:[]
- Can Haskell have lists of lists of lists? Why or why not?
- Why is the following list invalid in Haskell? Don't worry too much if you don't get this one yet.
[[1,2],3,[4,5]]
|
- 1 and 2 aren't valid Haskell, 3 is valid:
1:2:3:[]:[]. 1, 2 and 3 are integers, while [] is a list.
1:(2:3:[]):4:[]. Again, 1 and 4 are integers, and 2:3:[] is a list of integers.
(1:2:3:[]):[]:[]. This is valid Haskell, as 1:2:3:[] is a list of integers, and [] is an empty list (of any type).
- The first four are valid Haskell. The fifth is not.
[[],[1,2,3],[4,5,6]]. Both [1,2,3] and [4,5,6] are lists of integers. The whole list is a list of lists of integers. We can cons an empty list (of any type) in front of it.
[[]]. Not the empty list!. This is a list containing an empty list. The list itself is not empty, because it has one element!
[[],[]]. This is a list containing two empty lists.
[[1],[]]. This is the same list as the previous, but with a [1] as the first element instead of []. Since the list was a lists of lists, it now has become a list of integers.
[["hi"], [1]]. ["hi"] is a list of Chars while [1] is a list of integers.
- Yes, this is possible. For example:
[[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]]. Why? You can make a list of anything! If you already have a list of some type, then you can make a list of lists of that type. The example list would be written as: ((1:[]):(2:[]):(3:[]):[]):((4:[]):(5:[]):(6:[]):[]):((7:[]):(8:[]):(9:[]):[]):[]
- The list
[[1,2],3,[4,5]] is not valid because it is equivalent to (1:2:[]):3:(4:5:[]):[], where we try to cons elements that have different types (i.e. list and numeric). Lists in Haskell must be type-homogeneous. A valid list would be [[1,2],[3],[4,5]], equivalent to (1:2:[]):(3:[]):(4:5:[]):[].
[edit] A different notion of many
| Exercises |
- Write down the 3-tuple whose first element is 4, second element is "hello" and third element is True.
- Which of the following are valid tuples ?
(4, 4)
(4, "hello")
(True, "Blah", "foo")
- Lists can be built by consing new elements onto them: you cons a number onto a list of numbers, and get back a list of numbers. It turns out that there is no such way to build up tuples.
- Why do you think that is?
- Say for the sake of argument, that there was such a function. What would you get if you "consed" something on a tuple?
|
(4,"hello",True)
- They all are! Tuples aren't restricted to types.
- A tuple of two integers.
- A tuple of an integer and a string.
- A tuple of a boolean and two strings.
-
- A tuple like
("hello",True) is fundamentally different from a tuple like (3,"hello",True). A list with two elements is a list, just like a list with three elements.
- Unlike lists, we would obtain a tuple with a different type, because the tuple size would be bigger.
[edit] Projection functions
| Exercises |
- Use a combination of
fst and snd to extract the 4 from the tuple (("Hello", 4), True).
- Normal chess notation is somewhat different to ours: it numbers the rows from 1-8 and the columns a-h; and the column label is customarily given first. Could we label a specific point with a character and a number, like
('a', 4)? What important difference with lists does this illustrate?
|
snd (fst (("Hello", 4), True)) returns 4.
- Yes, we can! The difference between a tuple and a list is that all elements of a list must be of the same type (integers, booleans, etc.), but you can add elements to the list. The elements of a tuple can be of any type you want, like a tuple of an integer and a character in
(4, 'a'), but you can't change its size.
[edit] Tuples within lists and other combinations
| Exercises |
- Which of these are valid Haskell, and why?
fst [1,2]
1:(2,3)
(2,4):(2,3)
(2,4):[]
[(2,4),(5,5),('a','b')]
([2,4],[2,2])
|
-
- Not valid.
fst wants a tuple, [1,2] is a list.
- Not valid.
(2,3) is a tuple, and cons, (:), only works with lists.
- Not valid.
(2,3) is a tuple, and cons, (:), only works with lists.
- Valid. You'll get a list of tuples of an integer and an integer:
[(2,4)]
- Not valid. All elements of a list must be of the same type.
(2,4) and (5,5) are tuples of an integer and an integer, but ('a','b') is a tuple of a character and a character.
- Valid. This is a tuple of a list of integers and a list of integers.