1 module Main(main) where
  2 
  3 import qualified Data.ByteString as BS
  4 import qualified IO
  5 import System(getArgs)
  6 import Monad(mapM_)
  7 import qualified Scaffolding
  8 
  9 mergesort l =
 10     if (length l) <= 1 then l -- The list is already sorted.
 11     else -- Split the list into two halves and sort these.
 12         merge (mergesort lpart) (mergesort rpart) []
 13         where llen_half = (length l) `div` 2
 14               (lpart, rpart) = splitAt llen_half l
 15 
 16 -- Case #1: the right list is empty; just append the left list to the
 17 -- accumulator. The latter is reversed because we were prepending
 18 -- to it in case #3.
 19 merge lpart [] acc = (reverse acc) ++ lpart
 20 
 21 -- Case #2: the left list is empty; just append the right list to the
 22 -- (reversed) accumulator list.
 23 merge [] rpart acc = (reverse acc) ++ rpart
 24 
 25 -- Case #3: neither of the left/right lists to be merged is empty;
 26 -- prepend the lesser head element to the accumulator list.
 27 merge (l:ls) (r:rs) acc =
 28     if l <= r then merge ls (r:rs) (l:acc)
 29     else merge (l:ls) rs (r:acc)
 30 
 31 -- The main method, handles command line arguments, input and output.
 32 main = do
 33     args <- getArgs
 34     fileh <- case head args of
 35                 -- The text to be sorted is to be read from stdin.
 36                 "-" -> do return (Just IO.stdin)
 37                 -- The text to be sorted is to be read from the file
 38                 -- specified.
 39                 "-f" -> do Scaffolding.openFile (head (tail args))
 40                 -- Just sort the command line parameters.
 41                 _ -> do let sorted_args = mergesort args
 42                         IO.putStrLn ("mergesort(" ++ show args ++
 43                                      ") = " ++ show sorted_args)
 44                         return Nothing
 45     case fileh of
 46         -- Read text from file handle, sort it and print to stdout.
 47         Just fileh -> do text_to_sort <- Scaffolding.readLines fileh []
 48                          mapM_ BS.putStrLn (mergesort text_to_sort)
 49         -- We failed to open the file specified (if any).
 50         Nothing -> do return ()