dc :: (a -> Bool) -> (a -> [a]) -> (a -> b) -> (b -> b -> b) -> a -> b
--                         [a] non-empty!
dc trivial divide solve combine problem
  | trivial problem = solve problem
  | otherwise = foldr1 combine (map conquer (divide problem))
 where
  conquer = dc trivial divide solve combine

quickSort :: Ord a => [a] -> [a]
quickSort = dc trivial split id (++)
 where
  trivial xs = null xs || null (tail xs)
  split (x:xs) = [filter (<x) xs,[x],filter (>=x) xs]
