Skip to content

Instantly share code, notes, and snippets.

@rsslldnphy
Created July 2, 2013 18:49
Show Gist options
  • Save rsslldnphy/5911986 to your computer and use it in GitHub Desktop.
Save rsslldnphy/5911986 to your computer and use it in GitHub Desktop.
Merge sort in Haskell
module Main where
import System.Environment
main :: IO ()
main = do
args <- getArgs
mapM_ putStrLn $ sort args
sort :: (Ord a) => [a] -> [a]
sort [x] = [x]
sort xs = let (x1, x2) = bisect xs
s1 = sort x1
s2 = sort x2
in merge s1 s2
merge :: (Ord a) => [a] -> [a] -> [a]
merge xs ys = mergeIter [] (reverse xs) (reverse ys)
mergeIter :: (Ord a) => [a] -> [a] -> [a] -> [a]
mergeIter acc [] [] = acc
mergeIter acc (x:xs) [] = mergeIter (x:acc) xs []
mergeIter acc [] (y:ys) = mergeIter (y:acc) [] ys
mergeIter acc (x:xs) (y:ys)
| x > y = mergeIter (x:acc) xs (y:ys)
| otherwise = mergeIter (y:acc) (x:xs) ys
bisect :: [a] -> ([a], [a])
bisect xs = balance ([], xs)
balance :: ([a], [a]) -> ([a], [a])
balance (xs, ys) = if length xs >= length ys
then (xs, ys)
else let x = head ys
xs' = x:xs
ys' = tail ys
in balance (xs', ys')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment