I want to split [a] into ([a], [a]) by a pivot value and I have my code
splitList :: (Ord a) => a -> [a] -> ([a],[a])
splitList pivot list =
([x | x <- list, x <= pivot], [x | x <- list, x > pivot])
But it iterates the list twice to generate two lists, is there a way to iterate only once?
There are two possibilities, depending on if you want a tail recursive solution (and don’t care about reversing the order of elements), or a solution that consumes its argument lazily.
The lazy solution decides if the first element of the list goes into the first or into the second part and uses a simple recursion to process the rest of the list. This would be the preferred solution in most cases as laziness is usually more important than tail recursion:
However in some cases you care neither for the ordering of elements nor for laziness, but instead for speed. (For example when implementing a sorting algorithm.) Then a variant that uses an accumulator to build the result (see Accumulating Parameters: Getting rid of the ‘almost’ in “almost tail recursive” ) to achieve tail recursion would be more appropriate: