-- list merge sort listMergeSort cmpFunc list = head (until (\x -> null x || null (tail x)) mergeOneRound (makeLists list)) where -- `makeLists list` returns a list with every element of list -- turned into a singleton list makeLists [] = [] makeLists (x:xs) = [x]:makeLists xs -- `merge list1 list2` assumes both `list1` and `list2` are sorted; -- it returns the result of merging `list1` and `list2` such that -- the resulting list is also sorted. merge [] list2 = list2 merge list1 [] = list1 merge l1@(x:xs) l2@(y:ys) = if cmpFunc x y then x:merge xs l2 else y:merge l1 ys -- `mergeOneRound list` results in a list such that, each element -- inside the resulting list results from merging two successive -- elements of the original list. mergeOneRound (x1:x2:xs) = merge x1 x2:mergeOneRound xs mergeOneRound list = list incSort list = listMergeSort (<) list decSort list = listMergeSort (>) list -- This function works exactly like the `zip` function from the Prelude. zip' :: [a] -> [b] -> [(a, b)] zip' (x:xs) (y:ys) = (x, y):zip' xs ys zip' _ _ = [] -- `filter'` works exactly like the Prelude `filter` filter' :: (a -> Bool) -> [a] -> [a] filter' p [] = [] filter' p (x:xs) = if p x then x:ys else ys where ys = filter' p xs -- `map'` works exactly like the Prelude `map` map' :: (a -> b) -> [a] -> [b] map' _ [] = [] map' f (x:xs) = f x:map' f xs -- `sumOfDigits n` returns the sum of digits of n, where n is -- a nonnegative integer written in decimal notation. sumOfDigits :: Int -> Int sumOfDigits n = if n < 10 then n else n `mod` 10 + sumOfDigits (n `div` 10) -- `remBy9` returns n `mod` 9, assuming n is positive remBy9 :: Int -> Int remBy9 n = if yuck == 9 then 0 else yuck where yuck = until (< 10) sumOfDigits n