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 10 -- Top level mergesort function; this way the 'length' operator is 11 -- only invoked once on the original list. 12 mergesort l = 13 mergesort_ l llen 14 where llen = length l 15 16 -- Please note that the length of the list to be sorted is now passed 17 -- in as a parameter. 18 mergesort_ l llen = 19 if llen <= 1 then l -- The list is already sorted. 20 else -- Split the list into two halves and sort these. 21 merge (mergesort_ ls left_len) (mergesort_ rs right_len) 22 where (ls, rs) = splitAt left_len l 23 left_len = llen `div` 2 24 -- Takes care of lists with odd number of elements. 25 right_len = llen - left_len 26 27 merge ls [] = ls 28 merge [] rs = rs 29 merge (l:ls) (r:rs) = 30 if l <= r then l:(merge ls (r:rs)) else r:(merge (l:ls) rs) 31 32 -- The main method, handles command line arguments, input and output. 33 main = do 34 args <- getArgs 35 fileh <- case head args of 36 -- The text to be sorted is to be read from stdin. 37 "-" -> do return (Just IO.stdin) 38 -- The text to be sorted is to be read from the file 39 -- specified. 40 "-f" -> do Scaffolding.openFile (head (tail args)) 41 -- Just sort the command line parameters. 42 _ -> do let sorted_args = mergesort args 43 IO.putStrLn ("mergesort(" ++ show args ++ 44 ") = " ++ show sorted_args) 45 return Nothing 46 case fileh of 47 -- Read text from file handle, sort it and print to stdout. 48 Just fileh -> do text_to_sort <- Scaffolding.readLines fileh [] 49 mapM_ BS.putStrLn (mergesort text_to_sort) 50 -- We failed to open the file specified (if any). 51 Nothing -> do return ()