Perhaps a faster implementation:
mergeTwo :: Ord a => [a] -> [a] -> [a] mergeTwo x [] = x mergeTwo [] x = x mergeTwo (x:xs) (y:ys) = if x < y then x:(mergeTwo xs (y:ys)) else y:(mergeTwo (x:xs) ys) mergePairs :: Ord a => [[a]] -> [[a]] mergePairs [] = [] mergePairs (x:[]) = [x] mergePairs (x:y:tail) = mergePairs ((mergeTwo xy):(mergePairs tail)) mergeAll :: Ord a => [[a]] -> [a] mergeAll [] = [] mergeAll x = head $ mergePairs x
mergeTwo simply combines two lists. mergeAll just launches mergePairs and returns the head, if any. The magic happens in mergePairs, which takes a list of lists and combines pairs, than does it again and so on, while there are at least two lists.
It may be faster, imagine that you are working
merge = foldl merge2 []
It takes one long list and merges and merges. If you run it in [[1,2,3], [4,5,6], [7,8,9], [10,11,12]], it combines:
[] with [1,2,3]
[1,2,3] s [4,5,6]
[1,2,3,4,5,6] s [7,8,9]
[1,2,3,4,5,6,7,8,9] with [10,11,12]
But you want to keep lists about the same length. So you want to combine:
[1,2,3] s [4,5,6]
[7,8,9] s [10,11,12]
[1,2,3,4,5,6] s [7,8,9,10,11,12]
You can also consider the parallel implementation of mergePairs, this can be useful for multi-core processors. But I have no experience with this: /