[Haskell-cafe] comprehension generators from IO [a]'s ?

2005-12-19 Thread Steve Harris
[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
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] comprehension generators from IO [a]'s ?

2005-12-19 Thread Steve Harris
On 12/19/05, Chris Kuklewicz [EMAIL PROTECTED] wrote:
 Okay...that works.  Sweet.

 gdc x = ListT $ getDirectoryContents x

 get3levels top = runListT $ do
   b - gdc top
   c - gdc $ top++('/':b)
   d - gdc $ top++('/':b)++('/':c)
   return (b,c,d)

Yeah, that's awesome: just as readable as the comprehension
psuedo-code if not more-so.  I knew some monad wizards would step out
with something nice.

Thanks for spelling out what Andrew was getting at also, it would have
been lost on me.  I haven't yet ventured into using any monads but IO
yet, maybe ListT would be a good place to start.


 I feel bound to point out http://haskell.org/hawiki/ListTDoneRight which
 has more to say about the details of ListT

OK. Thanks to you both Chris and Andrew.

Steve
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe