#3127: need help to edit the Haskell script in Winhugs and documentation.
-----------------------+----------------------------------------------------
Reporter:  rjhelpdesk  |          Owner:                  
    Type:  task        |         Status:  new             
Priority:  normal      |      Component:  Documentation   
 Version:  6.10.1      |       Severity:  normal          
Keywords:              |       Testcase:                  
      Os:  Windows     |   Architecture:  Unknown/Multiple
-----------------------+----------------------------------------------------
 Both sections relate to the case study: Index for a document of text.

 SECTION  A:

 Given the attached Haskell code which produces an index of words, make the
 following alterations by modifying existing functions and including new
 functions where necessary – parts 1) to 5):

 1)      Where a word occurs N times on the same line, ensure that the line
 number occurs n times in the index entry for that word.

 2)      Allow words to be hyphenated and treat a hyphenated word as a
 single word.  However, for those words which are split over two lines,
 treat a split word as a single word without the hyphen.

 3)      Treat a capitalised word (one or more capitals) as being different
 from the word in all lower case (but they should still be sorted
 alphabetically) – unless it is at the start of a sentence with only the
 initial letter capitalised.  A sentence is terminated by a ‘.’, ‘?’ or
 ‘!’.

 4)      Make the output more readable in the form of an index table in
 columns with appropriate spacing and without brackets.

 5)      Include a user-friendly menu, so that the user can choose
 input/output file names or default files, and choose to rerun or exit.

 Parts 1) to 5) may be developed in any order.


 SECTION B:

 6)      For your version of function, makeIndex (only), show how an
 alternative ordering of the composed functions would provide a more
 efficient execution of makeIndex.  Justify your answer.

 7)      For the parts 1) to 5) above that you have attempted, discuss the
 use you have made of a) higher-order functions, b) list comprehension, c)
 monadic input/output, d) functional composition, and/or e) partial
 parameterisation (or Curried functions).  Include an evaluation of how
 useful your use of these concepts has been.



 import Prelude

 type Doc        =  String
 type Line       =  String
 type Word       =  String

 makeIndex  ::  Doc  ->  [ ([Int], Word) ]

 makeIndex
  =      shorten .       --      [([Int], Word)] -> [([Int], Word)]
         amalgamate .--  [([Int], Word)] -> [([Int], Word)]
         makeLists .     --      [(Int, Word)]   -> [([Int], Word)]
         sortLs .        --      [(Int, Word)]   -> [(Int, Word)]
         allNumWords .-- [(Int, Line)]   -> [(Int, Word)]
         numLines .      --      [Line]          -> [(Int, Line)]
         splitUp         --      Doc                     -> [Line]

 splitUp :: Doc -> [Line]

 splitUp [] = []
 splitUp  text
  = takeWhile (/='\n') text :    --      first line
    (splitUp .                   --      splitup other lines
     dropWhile (==’\n’) .        --      delete 1st newline(s)
     dropWhile (/='\n')) text    --      other lines

 numLines :: [Line] -> [(Int, Line)]

 numLines lines                          --      list of pairs of
  = zip [1 .. length lines] lines        --      line no. & line

 --      for each line
 --      a)      split into words
 --      b)      attach line no. to each word

 splitWords :: Line -> [Word]            --      a)

 splitWords [] = []
 splitWords  line
  = takeWhile isLetter line :            --      first word in line
         (splitWords .                   --      split other words
           dropWhile (not.isLetter) .    --      delete separators
           dropWhile isLetter) line      --      other words
    where
    isLetter ch
         = (‘a’<=ch) && (ch<=’z’)
           || (‘A’<=ch) && (ch<=’Z’)

 numWords :: (Int, Line) -> [(Int, Word)]        --      b)

 numWords (number, line)
  = map addLineNum ( splitWords line)    --      all line pairs
    where
    addLineNum word = (number, word)             --      a pair

 allNumWords :: [(Int, Line)] -> [(Int, Word)]

 allNumWords = concat . map numWords             --   doc pairs

 sortLs :: [(Int, Word)] -> [(Int, Word)]

 sortLs  [ ]  =  [ ]
 sortLs (a:x)
  = sortLs [b | b <- x, compare b a]     --      sort 1st half
    ++  [a]  ++                          --      1st in middle
    sortLs [b | b <- x, compare a b]     --      sort 2nd half
     where
     compare (n1, w1) (n2, w2)
      = (w1 < w2)                                --      1st word less
            || (w1 == w2 && n1 < n2)     --      check no.

 makeLists :: [(Int, Word)] -> [([Int], Word)]

 makeLists
  = map mk                                       --  all pairs
    where mk (num, word) = ([num], word)
                                                 --  list of single no.

 amalgamate :: [([Int], Word)] -> [([Int], Word)]

 amalgamate [ ] = [ ]
 amalgamate [a] = [a]
 amalgamate ((n1, w1) : (n2, w2) : rest)--  pairs of pairs
  | w1 /= w2             = (n1, w1) : amalgamate ((n2, w2) : rest)
  | otherwise    = amalgamate ((n1 ++ n2, w1) : rest)
         --      if words are same grow list of numbers

 shorten :: [([Int], Word)] -> [([Int], Word)]

 shorten
  = filter long                                  --      keep pairs >4
    where
         long (num, word) = length word > 4  --  check word >4

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3127>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to