[Haskell-beginners] partitionM

Daniel Fischer daniel.is.fischer at web.de
Thu Dec 3 16:06:19 EST 2009


Am Donnerstag 03 Dezember 2009 21:33:53 schrieb Tom Tobin:
> While working on some filesystem traversal code, I found myself
> wanting to use the 'partition' function from Data.List, but with the
> function 'doesDirectoryExist' in System.Directory (with type Filepath
> -> IO Bool).  I noticed that there was no 'partitionM' in
> Control.Monad, so I set out to write one.
>
> Here's what I ended up with:
> > import Control.Monad (foldM)
> >
> > partitionMHelper :: Monad m => (a -> m Bool) -> ([a],[a]) -> a -> m ([a],[a])

Before thinking much about it, I believe, a lazy pattern would help:

partitionHelper p ~(ts,fs) x = do ...

The reverse in partitionM still forbids infinite lists, I'll come to that later.

> > partitionMHelper p (ts,fs) x = do
> >     b <- p x
> >     return (if b then (x:ts,fs) else (ts,x:fs))
> >
> > partitionM :: (Monad m) => (a -> m Bool) -> [a] -> m ([a], [a])
> > partitionM p xs = foldM (partitionMHelper p) ([],[]) $ reverse xs
>
> This works for my trivial cases, but can fail with extremely large
> lists (not to mention being unable to take an infinite list and work
> properly when passed to something like 'take 5').  Is there a way to
> change the function to avoid having to traverse to the end of the list
> (via reverse) just to get the output in the proper order?  I started
> trying to write a "foldrM", but haven't gotten anywhere useful yet.
>
> Can someone point me in the right direction?




More information about the Beginners mailing list