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 ()