Lab: Haskell Mains
In today's lab, you'll develop several standalone Haskell programs that emulate command-line utilities. In particular, you will gain experience with do blocks, the IO system, command-line arguments, Haskell lists, and iteration via recursion.
Number
Write a main in number.hs that accepts a file name as its only command-line argument. It echoes the lines of the file but numbers them—starting at 1. For example, suppose we have this input file planets.txt:
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune
Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune
For this file, we would see this interaction in the shell:
> runhaskell number.hs planets.txt
1 Mercury
2 Venus
3 Earth
4 Mars
5 Jupiter
6 Saturn
7 Uranus
8 Neptune
> runhaskell number.hs planets.txt 1 Mercury 2 Venus 3 Earth 4 Mars 5 Jupiter 6 Saturn 7 Uranus 8 Neptune
To achieve a “mutating” line number, write a recursive helper function that iterates through the lines. Ensure that your solution works with any file.
Head
Write a main in head.hs that emulates the command-line head utility, which prints just the first n lines of a file. The command runhaskell head.hs planets.txt 6 produces this output:
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Mercury Venus Earth Mars Jupiter Saturn
You read about the lines function, which is helpful for this task. So is unlines. Also check out common list functions.
This program can be written in fewer than 10 lines of code.
Tail
Write a main in tail.hs that emulates the command-line tail utility, which prints just the last n lines of a file. The command runhaskell tail.hs planets.txt 4 produces this output:
Jupiter
Saturn
Uranus
Neptune
Jupiter Saturn Uranus Neptune
Your solution should be very similar to head.hs. This program can be written in around 10 lines of code.
Seq
Write a main in seq.hs that emulates the command-line seq utility, which prints a sequence of numbers between the two integers passed as command-line arguments. For example, the command runhaskell seq.hs 6 11 produces this output:
6
7
8
9
10
11
6 7 8 9 10 11
The sequence may also be descending. The command runhaskell seq.hs 2 -1 produces this output:
2
1
0
-1
2 1 0 -1
Ease the implementation by writing a helper function that takes in three parameters: a current value, a target value, and a delta. Have it print the current value and then decide whether to recurse.
This program can be written in fewer than 20 lines of code.
Submit
To receive credit for this lab, you must submit your .hs scripts on Canvas by Monday noon. Late labs or forgot-to-submits are not accepted because Monday at noon is when your instructor has time to grade.