filterM is already exist, partitionM is quite similar: -- | This generalizes the list-based 'partition' function. partitionM :: (Monad m) => (a -> m Bool) -> [a] -> m ([a], [a]) partitionM _ [] = return ([], []) partitionM p (x:xs) = do test <- p x (ys, ys') <- partitionM p xs return $ if test then (x:ys, ys') else (ys, x:ys')