Assignment 7: Haskell grade summary
Due: 5:00pm, Friday, October 19. Value: 30 pts.
Complete the problem from Assignment 4 using Haskell rather than Ruby.
To do this, you'll need to read a file. Below is an example
Haskell program for counting the number of lines, words, and
characters in a file. This example program defines forEachLine
function, a handy function that I strongly suggest using exactly as written
(though passing in another function than incrCounts
).
import System.IO
import Data.Map as Map
import Data.Set as Set
import Data.List as List
-- Given a file handle, a function, and a starting value,
-- execute a fold across the lines of the file. That is, return
-- f line0 x0 >>= f line1 >>= f line2 >>= ... >>= f lineZ
forEachLine :: Handle -> (String -> a -> IO a) -> a -> IO a
forEachLine handle f x0 =
do atEof <- hIsEOF handle
if atEof then
return x0
else
do line <- hGetLine handle
x1 <- f line x0
forEachLine handle f x1
incrCounts :: String -> (Int, Int, Int) -> IO (Int, Int, Int)
incrCounts line (ls, ws, cs) =
return (ls + 1, ws + length (words line), cs + length line + 1)
main :: IO ()
main =
do handle <- openFile "essay.txt" ReadMode
(ls, ws, cs) <- forEachLine handle incrCounts (0, 0, 0)
putStrLn (show ls ++ " " ++ show ws ++ " " ++ show cs)
Another useful utility function that you may want to include
is diffLists
: Given two lists of strings, diffLists
returns a list of each element from the first list
that is not in the second.
diffLists :: Ord a => [a] -> [a] -> [a]
diffLists allStrings exclStrings =
let exclSet = Set.fromList exclStrings
in List.filter (\x -> Set.notMember x exclSet) allStrings
Another function that you'll definitely want is the words
function included in the standard Prelude: words line
constructs a
list containing each space-separated word from line
as a separate
list element, very much like Python's line.split()
.
Finally, I suggest using a Map
for what the Python
implementation calls totals
. In particular, I found
Map.empty
, Map.insertWith
, Map.keys
, and
Map.toList
to be particularly helpful.
[Map documentation]