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