I have the following code: inversions :: (Ord a) => [a] -> Int inversions xs = snd $ countInv' (xs, length xs) countInv' :: (Ord a) => ([a], Int) -> ([a], Int) countInv' ([], _) = ([], 0) countInv' ([x], _) = ([x], 0) countInv' (xs, n) = (sorted, leftInv + splitInv + rightInv) where leftLen = n `div` 2 rightLen = n - leftLen (left, right) = splitAt leftLen xs (sortedLeft, leftInv) = countInv' (left, leftLen) (sortedRight, rightInv) = countInv' (right, rightLen) (sorted, splitInv) = countSplitInv' (sortedLeft, leftLen) (sortedRight, rightLen) countSplitInv' :: (Ord a) => ([a], Int) -> ([a], Int) -> ([a], Int) countSplitInv' ([], _) ([], _) = ([], 0) countSplitInv' (xs, _) ([], _) = (xs, 0) countSplitInv' ([], _) (xs, _) = (xs, 0) countSplitInv' (x : xs, nx) (y : ys, ny) | x > y = (y : sortedY, nx + splitInvY) | otherwise = (x : sortedX, splitInvX) where (sortedX, splitInvX) = countSplitInv' (xs, pred nx) (y : ys, ny) (sortedY, splitInvY) = countSplitInv' (x : xs, nx) (ys, pred ny) main :: IO () main = do contents <- getContents print $ inversions (map read (lines contents) :: [Int]) How could I write this code in a way that is more idiomatic, reduces the amount of repetition, and reduces the amount of data being copied?