In this lab you'll learn how to write stand-alone programs in Haskell.
This week's lab is divided into two parts:
Let's look at these separately.
Write a program called hello1 that prints hello,
world!.
Write a program called hello2 that prints a prompt asking
you to enter your name, grabs your name from stdin, and prints
hello, <your name>!
(with <your name> appropriately substituted, of course).
Write a program called hello3 that prints out its
command-line arguments, one per line.
None of these programs requires more than 7 lines of code.
Now that you have that under your belt, it's time to write some more
interesting programs. You're going to re-implement the Unix utility programs
cat, sort and uniq in Haskell -- call
them hcat, hsort and huniq. They will
not implement all the options of the Unix programs, of course (unless you
want serious extra credit ;-)). However, each of them has to be able
to read input either from a named file (or files, in the case of
hcat) or from stdin, and they should all dump their
output to stdout. Use a quicksort algorithm for the
hsort program. None of the three programs should add any extra
lines (not even newlines) that weren't in the original files.
Read (or at least skim) the man pages for cat,
sort, and (especially) uniq to make sure you know
what these programs do. In brief, cat copies (concatenates)
files to the standard output stream, sort sorts the lines in a
file, and uniq removes consecutive duplicated lines in a file
(not all duplicated lines, just the consecutive ones).
For the hsort and huniq programs, do the sorting
or uniq'ing in a separate function that does not have an IO
type. Because of laziness, it's just as efficient to use this function on a
list of all the strings in all the files as it would be to do the processing
inside the input/output handling code, and it's much more modular. This is
one of the hidden benefits of laziness; it helps you decompose problems
better.
Once you're done, it should be possible to do this:
% hcat *.hs | hsort | huniq | more
and see all the unique lines in your programs. (If you don't understand
the above line, you need to read about pipes in shell commands. Do
"man bash" to learn more.) For fun, try to figure out how much
slower the Haskell versions are relative to the normal Unix utilities written
in C.
Here are some functions you may find useful:
putStr and putStrLngetChargetLinehsetBufferingopenFilegetContentshGetContentshCloseSystem.getArgsmapM_interact (especially the idiom interact
id -- what does that do?)lines(!!) operator for accessing lists by indexIO and System libraries (use the
import statement to import them)The files hello1.hs, hello2.hs,
hello3.hs, hcat.hs, hsort.hs and
huniq.hs.
make to make all the programs and make clean to get
rid of the compiled programs and intermediate files.
As always, the tutorial A Gentle Introduction to Haskell, by Hudak, Peterson and Fasel.
The GHC user's guide, specifically the part relating to compiling stand-alone executables.