COMP1011 Exercises for Week 08 | |
---|---|
Computing 1A 05s2 |
Last updated
Tue 19 Jul 2005 14:37
Mail cs1011@cse.unsw.edu.au |
The second part of this week's lab is about Unix. Please keep in mind that the Unix material covered in the lectures, tutes, and labs is assessable material, just like programming in Haskell. To solve this week's Unix exercises, you will need to understand how a couple of basic Unix tools work, which means that you have to read some additional documentation about these tools. You won't be able to do this in the supervised lab time. Hence, you should read the documentation before going to your lab and tute; see Ex 2 below for details on what to read.
This week's exercises require the use of three different modules:
BookVideoCD.hs
, ProductDB.hs
, and
Lab08.hs
. You will create the first two modules in the
following, first exercise. All the code implemented in the remaining
exercises should go into the third module Lab08.hs
.
Implement a module with the following interface
module BookVideoCD ( Title, Author, Artist, Product(..), getTitle ) where
containing the types and functions from the tutorial exercises.
Furthermore, download the module ProductDB.hs
.
bookAuthors
Implement a function
bookAuthors :: [Product] -> [Author]
that returns all book authors in a given product list. Use the function
List.nub
to remove duplicates from the list of authors.
The module List
is part of the Haskell standard libraries
and you can import it without having to define the module. Apply
nub
to lists like [1,2,1,1]
to see what it
does, before using it.
Next, implement a function that allows us to print a product list in a
nice format. If we just print
a product list, we get
Lab08> print products [Book "Snowcrash" "Neil Stephenson",CD "Death to the Pixies" "The Pixies" 12, CD "101 Damnations" "Carter USM" 11,Video "Underworld",Book "Consider Phlebas" "Iain M. Banks",CD "Empires" "VNV Nation" 10,Video "The Matrix",Book "Excession" "Iain M. Banks"]
which obviously doesn't look very nice. We attack the problem of
producing some nice output in two steps: First, we implement a function
showProduct
, which produces a nice output for a single
product; and second, we implement showProducts
, which does
the same for a list of products (of course by using
showProduct
).
The two functions have the following type signatures:
showProduct :: Product -> String showProducts :: [Product] -> String
So, they just convert a product, or list of products, into a string,
which we, then, can print using putStr
. For example, we
have
Lab08> putStr (showProduct (CD "Empires" "VNV Nation" 10)) CD : "Empires", VNV Nation; 10 tracks Lab08> putStr (showProducts products) Book : "Snowcrash", Neil Stephenson CD : "Death to the Pixies", The Pixies; 17 tracks CD : "101 Damnations", Carter USM; 11 tracks Video: "Underworld" Book : "Consider Phlebas", Iain M. Banks CD : "Empires", VNV Nation; 10 tracks Video: "The Matrix" Book : "Excession", Iain M. Banks
Here are some hints that should help you with the exercise:
"
) into a string by prefixing
it with a backslash (\
) - i.e., try what GHCi does when
you enter putStr "\"Quoted text\""
(note the similarity
to using \n
to represent a line break).
showProducts
, you can save
yourself a recursion by using the higher-order function
map
.
unlines
that we discussed earlier and which is provided by the
Prelude
.
When you have completed the above exercises show them to your tutor for this week's core mark.
In the lecture, we saw a number of Unix tools without discussing, in any detail, their working and the many options they take. To look up the details of these tools, you have got a number of alternatives:
<topic>
issue the command info
<topic>
. For example, info info
explains the
help system, info File permissions
explain Unix file
permissions, and info ls
describes the ls
command. To get an overview over all basic Unix tools and topics,
type info coreutils
Implement a shell script that prints the sum of the number of lines of all Haskell files in the current directory disregarding empty lines and lines that start with -- (i.e., dash dash, and hence, contain no code, but only contain a comment).
Hint: Read up on how to use the Unix tool
grep
. Keep in mind that you don't have to understand all
the details about grep
(of which there are many), but you
definitely need to understand the basics of how regular
expressions work.
Hint #2: Have a look at the options taken by the
command wc
. There is an easier way to restrict its output
to the lines of a file (omitting the word and character count) than that
discussed in the lecture and tute.
When you have completed the above exercise show them to your tutor for this week's advanced mark.
The following are additional exercises to help you getting practice in programming. They are not part of the lab mark, but should help you understand some of the material covered in the lecture.
lookupTitle
Implement a function
lookupTitle :: Title -> [Product] -> Maybe Product
that extracts a product with matching title from the product list if
present. If there is no product with the given title in the database,
Nothing
is returned. For example,
Lab08> lookupTitle "101 Damnations" products Just (CD "101 Damnations" "Carter USM" 11) Lab08> lookupTitle "Consider Phlebas" products Just (Book "Consider Phlebas" "Iain M. Banks") Lab08> lookupTitle "Dark Star" products Nothing
Important Note: Maybe a
is already
predefined in the Prelude
. So, just use it without
explicitly adding the definition to your module.
lookupTitles
Next, implement
lookupTitles :: [Title] -> [Product] -> [Product]
Given a list of titles, this function extracts, for each title, the
corresponding product from the second list. Titles that have no
matching product in the list are ignored. You must use
lookupTitle
to do the actual lookup for each title.
Examples of the application of lookupTitles
are
Lab08> lookupTitles [] products [] Lab08> lookupTitles ["Excession", "Dark Star", "Snowcrash"] products [Book "Excession" "Iain M. Banks",Book "Snowcrash" "Neil Stephenson"] Lab08> lookupTitles ["Dark Star", "Boys Don't Cry"] products [] Lab08> putStr (showProducts (lookupTitles ["Excession", "Dark Star", "Snowcrash"] products)) Book : "Excession", Iain M. Banks Book : "Snowcrash", Neil Stephenson
Hint: The higher-order function map
can again save
you one recursive definition. However, this time the use of
map
is a bit more complicated. In fact, you must in
addition use a local function definition (ie, one in a
where
clause).
showProducts
revisited
Re-implement showProducts
such that the output is in
tabular form, i.e.,
Lab08> putStr (showProducts products) Book : "Snowcrash" Neil Stephenson CD : "Death to the Pixies" The Pixies 17 tracks CD : "101 Damnations" Carter USM 11 tracks Video: "Underworld" Book : "Consider Phlebas" Iain M. Banks CD : "Empires" VNV Nation 10 tracks Video: "The Matrix" Book : "Excession" Iain M. Banks
The tricky part here is that you cannot make any assumptions about the length of the longest title or author and artist. In other words, if the product database is extended by a product, which has an even longer title, your function should still print a properly aligned table.
Hint: showProduct
in its current form is
not a suitable helper function for this improved version of
showProducts
.