-- Produce an alphabetic list of the words in a file that don't appear in -- a given dictionary. -- -- We can break the problem up into three smaller problems like this: -- -- -- ___________ _____________ ____________ -- |get all the| |check if each| |put words in| -- -------->|words from |------>|one is in the|--------->|alphabetical|--------> -- file |the file | words | dictionary | misspelt | order | sorted -- contents ----------- ------------- words ------------ misspelt -- wordsFromString misspelt sort words -- -- -- The output from wordsFromString is the input to misspelt and the output -- from misspelt is the input to sort. That is, the check function is -- the composition of those three functions. -- -- The sample dictionary modules Dictionary1.hs and Dictionary2.hs are -- specialised for SpellTest.hs and Spell.hs respectively. uncomment -- whichever is appropriate. import Char(isAlpha) import Dictionary1 -- import Dictionary2 type Word = String type Words = [Word] -- spellCheck: -- -- spellCheck is the main function. It reads a file and applies the check -- function to find all misspelt words in that file. spellCheck :: FilePath -> IO() spellCheck f = do{contents <- readFile f; putStr (unlines (check contents))} -- The input to the check function is the contents of the file to be checked -- for misspellings. check :: String -> Words check = sort . misspelt . wordsFromString -- wordsFromString: -- -- A word is defined to be a sequence of letters. We need a function -- to determine if a character is a letter. There's a standard -- function isAlpha which has the following definition: -- -- isAlpha :: Char -> Bool -- isAlpha c = isUpper c || isLower c -- -- isUpper c = c >= 'A' && c <= 'Z' -- isLower c = c >= 'a' && c <= 'z' -- -- skipToLetter is the string after removal the of initial characters -- that aren't letters. -- -- firstWord is the first word in the string. -- -- restOfString is what is left if we remove the first word from the string. -- -- We use recursion to find all the words in restOfString. -- If firstWord is empty, there are no more words in the string. wordsFromString :: String -> Words wordsFromString s | firstWord == "" = [] | otherwise = firstWord:wordsFromString restOfString where skipToLetter = dropWhile (not . isAlpha) s firstWord = takeWhile isAlpha skipToLetter restOfString = dropWhile isAlpha skipToLetter -- misspelt: -- -- misspelt just removes all the words that are in the dictionary from -- the list of words found in the file. misspelt :: Words -> Words misspelt = filter (notInDictionary) -- notInDictionary is true if a word is not in the dictionary. -- notElem is a standard function that determines if a value is in a list. notInDictionary :: Word -> Bool notInDictionary w = w `notElem` dictionary -- sort: -- -- We require a function that sorts into ascending order a list of strings. -- The insertion sort function developed in section 7 of the lecture notes -- will satsify these requirements. sort :: Ord a => [a] -> [a] sort [] = [] sort (x:xs) = insert x (sort xs) where insert x [] = [x] insert x (y:ys) | x <= y = x : y : ys | otherwise = y : insert x ys