use Universal == < use Optional None Some uncons : [a] -> Optional (a, [a]) uncons a = match at 0 a with None -> None Some hd -> Some (hd, drop 1 a) merge : (a -> a -> Boolean) -> [a] -> [a] -> [a] merge lte a b = go acc a b = match (uncons a, uncons b) with (None, _) -> acc ++ b (_, None) -> acc ++ a (Some (h1,t1), Some (h2,t2)) -> if lte h1 h2 then go (snoc acc h1) (drop 1 a) b else go (snoc acc h2) a (drop 1 b) go [] a b -- let's make sure it works > merge (<) [1,3,4,99,504,799] [0,19,22,23] isEmpty : [a] -> Boolean isEmpty a = size a == 0 halve : [a] -> Optional ([a], [a]) halve as = if isEmpty as then None else Some (take (size as / 2) as, drop (size as / 2) as) sort : (a -> a -> Boolean) -> [a] -> [a] sort lte as = if size as < 2 then as else match halve as with None -> as Some (left, right) -> l = sort lte left r = sort lte right merge lte l r -- let's make sure it works > sort (<) [3,2,1,1,2,3,9182,1,2,34,1,23] -- > sort (<) ["Dave", "Carol", "Eve", "Alice", "Bob", "Francis", "Hal", "Illy", "Joanna", "Greg", "Karen"] -- > sort (<) [3,2,1,1,2,3,9182,1,2,34,1,"oops"] -- > merge (<) [1,4,5,90,102] ["a", "b"]