Lab 4: Understanding Lists in Haskell - Comprehension and Generation, Lab Reports of Computer Science

An introduction to lists in haskell, focusing on list comprehension and generation. How to create lists using list comprehensions with different generators and filters, and provides examples of list comprehensions and their usage. It also covers the concept of infinite lists and the difference between list comprehensions and other list generation methods.

Typology: Lab Reports

Pre 2010

Uploaded on 08/09/2009

koofers-user-use
koofers-user-use 🇺🇸

10 documents

1 / 2

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Lab 4: Comprehending Lists
You may work singly or in pairs on this lab: If you work with a partner,
turn in a single solution with both names on it.
1 Lists
In Haskell, a list is a sequence of values, all having the same type. For example,
[1,3,5,6] is a 4-element list of Ints, whereas [True,False,False,True,False]
is a 5-element list of Bools.
Generally speaking, the lists that we’ll be using will be finite (in particular, all of
the lists we use in this lab will be finite, with one exception). However, Haskell
does allow us to define and use infinite lists; we’ll talk about the use of infinite
lists later this semester.
In Haskell, strings are lists of characters, just as strings in C are just arrays of
characters. If you evaluate the expression [’a’, ’b’, ’c’] in the Hugs inter-
preter, you’ll get the following response: "abc".
Haskell provides mechanisms for the easy definition of certain lists. Evaluate each
of the following at the Hugs prompt:
[1 .. 10]
[15 .. 20]
[15 .. (20-5)]
[’q’ .. ’z’]
[14 .. 2]
You no doubt noticed the pattern here: for numbers, characters and other enu-
merated types (something else we haven’t talked about yet!), the expression
[m.. n]yields the list [m,m+ 1,m+ 2, ..., n]. In the cases where n
is less than m(such as the last example above), the empty list [] is returned.
More generally, the expression [m,p.. n]yields the list
[m,m+ (pm),m+ 2(pm),m+ 3(pm), ..., n0]
where n0is as close as possible to nwithout exceeding it. The book explains this
notation a bit more precisely, but you should have the basic idea. Evaluate each
of the following, to make sure you understand this notation:
[1,3 .. 10]
[15,15.5 .. 20]
[1.0, 1.2 .. 2.0]
[’a’,’d’ .. ’z’]
[10,8 .. -3]
[1,2 .. 0]
What do you think would happen if you evaluated the following expression? (You
can try it out to check your answer if you want, but be prepared to type C-c C-c
to stop the Hugs evaluation; you may also need to delete the Hugs buffer (C-x k).)
[9,9 .. 10]
2 List Comprehensions
Haskell also provides a powerful mechanism known as list comprehension, which
provides a convenient way for defining lists from previous lists.
A list comprehension typically comprises three parts: (1) a generator, (2) some
number (sometimes zero) of tests, and (3) a transformation. The generator ex-
tracts elements from an existing list, the tests work as filters to select some of
those extracted elements, and the transformation uses those selected elements to
create the resulting list.
For example, consider the following expression:
[ (x,True) | x <- [1 .. 20], even x, x < 15 ]
Here, x <- [1 .. 20] is the generator, the tests are even x and x < 15,
and (x,True) is the transformation. This expression creates a list of all pairs
(x,True), where xis between 1and 20, even, and less than 15. (Recall that
even is defined in Haskell’s standard Prelude.)
Evaluate this expression, and notice that the elements appear in the order that
they were generated. Compare that result to the evaluation of the following:
[ (x,True) | x <- [20, 19 .. 1], even x, x < 15 ]
Once again, the elements appear in the order that they were generated.
As another example, consider the following:
[ [m+n] | (m,n) <- [(3,6), (7,3), (8,4), (1,3), (4,8)], n == 2*m]
CIS 252 (Spring 2009) Introduction to Computer Science Page 1
pf2

Partial preview of the text

Download Lab 4: Understanding Lists in Haskell - Comprehension and Generation and more Lab Reports Computer Science in PDF only on Docsity!

Lab 4: Comprehending Lists

You may work singly or in pairs on this lab: If you work with a partner, turn in a single solution with both names on it.

1 Lists

In Haskell, a list is a sequence of values, all having the same type. For example, [1,3,5,6] is a 4-element list of Ints, whereas [True,False,False,True,False] is a 5-element list of Bools.

Generally speaking, the lists that we’ll be using will be finite (in particular, all of the lists we use in this lab will be finite, with one exception). However, Haskell does allow us to define and use infinite lists; we’ll talk about the use of infinite lists later this semester.

In Haskell, strings are lists of characters, just as strings in C are just arrays of characters. If you evaluate the expression [’a’, ’b’, ’c’] in the Hugs inter- preter, you’ll get the following response: "abc".

Haskell provides mechanisms for the easy definition of certain lists. Evaluate each of the following at the Hugs prompt:

[1 .. 10] [15 .. 20] [15 .. (20-5)] [’q’ .. ’z’] [14 .. 2]

You no doubt noticed the pattern here: for numbers, characters and other enu- merated types (something else we haven’t talked about yet!), the expression [m .. n] yields the list [m, m + 1, m + 2, ..., n]. In the cases where n is less than m (such as the last example above), the empty list [] is returned.

More generally, the expression [m, p .. n] yields the list

[m, m + (p − m), m + 2(p − m), m + 3(p − m), ..., n′]

where n′^ is as close as possible to n without exceeding it. The book explains this notation a bit more precisely, but you should have the basic idea. Evaluate each of the following, to make sure you understand this notation:

[1,3 .. 10] [15,15.5 .. 20]

[1.0, 1.2 .. 2.0]

[’a’,’d’ .. ’z’] [10,8 .. -3] [1,2 .. 0]

What do you think would happen if you evaluated the following expression? (You can try it out to check your answer if you want, but be prepared to type C-c C-c to stop the Hugs evaluation; you may also need to delete the Hugs buffer (C-x k).)

[9,9 .. 10]

2 List Comprehensions

Haskell also provides a powerful mechanism known as list comprehension, which provides a convenient way for defining lists from previous lists. A list comprehension typically comprises three parts: (1) a generator, (2) some number (sometimes zero) of tests, and (3) a transformation. The generator ex- tracts elements from an existing list, the tests work as filters to select some of those extracted elements, and the transformation uses those selected elements to create the resulting list. For example, consider the following expression:

[ (x,True) | x <- [1 .. 20], even x, x < 15 ]

Here, x <- [1 .. 20] is the generator, the tests are even x and x < 15, and (x,True) is the transformation. This expression creates a list of all pairs (x,True), where x is between 1 and 20 , even, and less than 15. (Recall that even is defined in Haskell’s standard Prelude.) Evaluate this expression, and notice that the elements appear in the order that they were generated. Compare that result to the evaluation of the following:

[ (x,True) | x <- [20, 19 .. 1], even x, x < 15 ]

Once again, the elements appear in the order that they were generated. As another example, consider the following:

[ [m+n] | (m,n) <- [(3,6), (7,3), (8,4), (1,3), (4,8)], n == 2*m]

CIS 252 (Spring 2009) — Introduction to Computer Science Page 1

Lab 4: Comprehending Lists

This expression creates a list of lists of Ints, using only those pairs whose second component is exactly twice the first component. This expression also demon- strates how you can use patterns (e.g., (m,n)) to isolate particular pieces of data.

We can also use list comprehensions to define more general functions. For exam- ple, the following function is a generalization of the previous expression:

sampleFun :: [(Int,Int)] -> [[Int]] sampleFun pairList = [[m+n] | (m,n) <- pairList, n == 2*m]

The type declaration of sampleFun indicates that the function accepts a list of pairs of Int and returns a list of lists of Ints.

Try the above function out on the following arguments:

sampleFun [(3,6), (7,3), (8,4), (1,3), (4,8)] sampleFun [(3,7), (8,9), (1,3)]

Finally, the following example (taken from page 81 of the book) demonstrates that list comprehensions can be used as part of a larger function. The following two functions determine whether a given list of integers contains only even (or only odd) numbers:

allEven, allOdd :: [Int] -> Bool

allEven xs = (xs == [x | x <- xs, x ‘mod‘ 2 == 0]) allOdd xs = ([] == [x | x <- xs, x ‘mod‘ 2 == 0])

For example, try evaluating the following:

allEven [1 .. 20] allOdd [1 .. 20] allEven [1,3 .. 20] allOdd [1,3 .. 20] allEven []

Note that the condition x ‘mod‘ 2 == 0 could be replaced by even x and pro- duce the same result.

3 Your Problems

Create each of the following lists using a list comprehension, with the list [ .. 10] as the generator. That is, each of your answers should have the following

form, where you fill in the blanks and only the blanks:

[ ____________ | x <- [1 .. 10] ___________________________ ]

To be explicit, your answers must use the generator x <- [1 .. 10], and you must not embed this comprehension within any additional function calls: for example, do not use reverse [ x | x <- [1 .. 10]] to create the list [10,9,8,7,6,5,4,3,2,1]. Likewise, [ x | x <- [10, 9 .. 1]] and [ x | x <- reverse [1 .. 10]] are forbidden. Note, however, that you can use anything you want (including auxiliary func- tions) to fill in the blanks themselves.

  1. [10,20,30,40,50,60,70,80,90,100]
  2. [True,False,True,False,True,False,True,False,True,False]
  3. [[1],[3],[5],[7],[9],[11]]
  4. [(3,True),(6,True),(9,True),(12,False),(15,False),(18,False)]
  5. [[10],[8],[6],[4],[2]]
  6. [(5,False),(10,True),(15,False),(40,False)]
  7. [(11,12),(13,14),(15,16),(17,18),(19,20)]
  8. [[5,6,7],[5,6,7,8,9],[5,6,7,8,9,10,11],[5,6,7,8,9,10,11,12,13]]
  9. [22,17,12,7,2]
  10. [[4],[6,4],[8,6,4],[10,8,6,4],[12,10,8,6,4]]

What to Hand In: Hand in a transcript that demonstrates that your answers are correct. Your transcript may either be the full transcript of your session, or just a transcript run after you have figured out all the correct answers. If you choose the former, please make the grading task easier by highlighting the answers that should be graded.

Due: This lab is due by noon on Friday, February 6. You should submit it to the labeled bin in CST 3-212.

CIS 252 (Spring 2009) — Introduction to Computer Science Page 2