CA215 Languages and
Computability
Functional Programming Lab
7: Modifying an Existing Program
Aim: The aim of
this week's exercise is to modify an existing program. The program that you
will be working with is the spelling checker discussed in lectures.
You will
need to make use of the following scripts in this class:
Spell.hs: this is the main program script which defines
a spellchecker
SpellTest.hs: this is a small test file
Dictionary1.hs: this is a dictionary
tailored to check the spelling in SpellTest.hs
Dictionary2.hs: this is a dictionary
tailored to check the spelling in the main script Spell.hs
1. Modifying
the Spelling Checker Program
There are
several shortcomings of the spelling checker program discussed in lectures:
1. It should
treat apostrophes as letters. That is, it should consider its to be one word rather than the two words it and s. You only
need to slightly modify one of the existing functions to fix this. To write a
character constant for the apostrophe in Haskell you must write \, so a function to test whether a character is
an apostrophe can be written as follows:
isApostrophe :: Char -> Bool
isApostrophe c = c == '\''
2. If the same
word is misspelt the same way several times, it will be included several times
in the list of misspelt words. To avoid this, we need a function to remove
repeated elements from a list. There is such a function in the List.hs library module, but since you will be looking
for duplicates in a sorted list, you should design a more efficient version.
(This may
be familiar from previous practical exercises - I suggest you look back through
your solutions). When you have developed a function to remove repeated elements
from a sorted list, you need to decide how to use it to modify the spelling checker
script.
3. If our
intention is to apply this checker to Haskell scripts, then it should only
check the spelling in those lines which are comments (i.e. which start with --). Otherwise, it will report spelling errors
like x, xs, isAlpha and so on. To do this, you need to write a
function that removes the lines of Haskell code from a string containing the
contents of the file.
Rather than
immediately breaking the string into words using wordsFromString, I suggest that you first break it into the individual
lines of the file, then filter out those not beginning with -- before breaking it into words.
You may
find the standard functions lines :: String -> [String] and unlines :: [String] -> String useful for this task. When applied to a string
containing newline characters \n, lines returns a list of strings by breaking the
original string into lines. The newline characters are removed from the result.
The unlines function is the inverse of lines. If you are not sure about the behaviour of
these functions, I suggest that you experiment with them first. Examples of lines and unlines usage:
Main> lines "aa\nbb\ncc"
["aa", "bb","cc"]
Main> lines "Good morning. How are you?\nFine, thank you.\nGrand."
["Good morning. How are you?", "Fine, thank you.","Grand."]
Main> unlines ["aa","bb","cc","dd","ee"]
"aa\nbb\ncc\ndd\nee"
Main> unlines ["My","name","is","Sylwia"]
"My\nname\nis\nSylwia\n"
Modify the
script spell.hs so that apostrophes
are treated as letters, misspelt words are only listed once and only lines
starting with -- are checked.
2. Ordered
Dictionaries
You may
notice that the two example dictionaries are both sorted into lexicographical
order, but the misspelt function
takes no advantage of this fact. Modify your script to make it (slightly) more
efficient by using a search that assumes that the dictionary is in ascending
lexicographical order.