import Data.List (partition) unpartition :: [Bool] -> [a] -> [a] -> [a] unpartition [] _ _ = [] unpartition (True:ps) (a:as) bs = a:unpartition ps as bs unpartition (False:ps) as (b:bs) = b:unpartition ps as bs onPartitions :: (Monad m) => (a -> Bool) -> ([a] -> m [b]) -> ([a] -> m [b]) -> [a] -> m [b] onPartitions p t f xs = let partitions = map p xs (pt, pf) = partition snd (zip xs partitions) in do yt <- t (map fst pt) yf <- f (map fst pf) pure $ unpartition partitions yt yf main :: IO () main = do onPartitions even (traverse print) (traverse print) [1..10] pure ()