
[reposted from haskell mailing list where I got no bites :) ] Folks, I'm new to using monads, and I'd like some help improving a function definition that I wrote and which works, but for which I think there should be a clearer way to write it. What I'm after is something like: -- (psuedo-code) [(b,c,d) | b <- getDirectoryContents a_dir, c <- getDirectoryContents (a_dir ++ "/" ++ b), d <- getDirectoryContents (a_dir ++ "/" ++ b ++ "/" ++ c) ], ie. where the generators feed from IO actions instead of lists, but I gather this comprehension style isn't supported, which is too bad because it's really easy to read. (Is this what was meant by "monad comprehensions" that I've heard reference to?) Here's how I actually wrote it, using nested folds: import System.IO -- Load directory entries 3 levels deep under a_dir, as list of tuples (b,c,d) load3DirLevels :: FilePath -> IO [(String,String,String)] load3DirLevels a_dir = do bs <- getDirectoryContents a_dir foldM (\tups b -> do cs <- getDirectoryContents (a_dir ++ "/" ++ b) foldM (\tups' c -> do ds <- getDirectoryContents (a_dir ++ "/" ++ b ++ "/" ++ c) foldM (\tups'' d -> do return $ (b, c, d) : tups'' ) tups' ds ) tups cs ) [] bs This function isn't so clear at a glance, and yet what it's doing seems like a pretty common thing to want to do: are there any library functions for monads (or IO in particular) that make this sort of thing easier, or should I to try and write my own function? Looks not too difficult to write but I think I might miss something important if I didn't ask first... How would you do it? Thanks Steve