[Haskell-cafe] Re: Filesystem questions

2007-10-14 Thread apfelmus

Yitzchak Gale wrote:

I wrote:

...a tool for recursing through directories...
How about a built-in function that represents a directory tree
as a lazy Data.Tree?


Bryan O'Sullivan wrote:

See System.FilePath.Find in
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/FileManip-0.2



-- List all directories in the tree rooted at the given path
traverseDirectories :: MonadIO m =
  TraversalDirection - FilePath - ListT m Directory

You could plug the above into your machinery for
recursion predicates and all the other nice stuff.


Or - getting back to the lazy Data.Tree idea -
we could define TreeT, analgous to ListT:

newtype TreeT m a = NodeT (m (a, TreeT (ListT m) a))

and give it a nice Monad instance. Then you can prune
and filter trees in a natural way, inside the monad.


Eh, isn't that what ListT is already for? I mean,

  type Directory = FilePath

  contents :: MonadIO m = Directory - m [FilePath]

  liftList :: Monad m = m [a] - ListT m a
  runList  :: Monad m = ListT m a - m [a]

allows you to prune the directory tree in whatever way you like it. 
Here's an example top-down traversal that lists all non-directories:


  allFiles :: MonadIO m = Directory - m [FilePath]
  allFiles d = runList $ do
 f - liftList $ contents d
 if isDirectory f
   then allFiles f
   else return f

In other words, ListT is like one of those iterators I keep hearing from 
the Python/Java/.../imperative world (except that you can't suspend a 
traversal once started).


Regards,
apfelmus

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


Re: [Haskell-cafe] Re: Filesystem questions

2007-10-14 Thread Yitzchak Gale
Hi apfelmus,

I wrote:
 ...a tool for recursing through directories...
 How about a built-in function that represents a directory tree
 as a lazy Data.Tree?

 -- List all directories in the tree rooted at the given path
 traverseDirectories :: MonadIO m =
   TraversalDirection - FilePath - ListT m Directory

 Or - getting back to the lazy Data.Tree idea -
 we could define TreeT, analgous to ListT:
 newtype TreeT m a = NodeT (m (a, TreeT (ListT m) a))
 and give it a nice Monad instance. Then you can prune
 and filter trees in a natural way, inside the monad.

apfelmus wrote:
 Eh, isn't that what ListT is already for?
 ...allows you to prune the directory tree in whatever way you like it.
 Here's an example top-down traversal that lists all non-directories:

allFiles :: MonadIO m = Directory - m [FilePath]
allFiles d = runList $ do
   f - liftList $ contents d
   if isDirectory f
 then allFiles f
 else return f

 In other words, ListT is like one of those iterators I keep hearing from
 the Python/Java/.../imperative world

Well, yes, you could also use it that way. And yes,
years ago they used to do it that way in Python.
Where every user has to build in the logic to
discover the tree structure manually, as they
iterate along.

But it turns out that it is much more natural and
convenient to be given the tree structure pre-built,
and then just traverse it. You need some laziness
to avoid visiting directories that you don't care about
and might be costly to visit.

Python currently uses generators to get the laziness.
Bryan uses unsafe IO, together with his recursion predicates
and filter predicates.

My first proposal was just a minor modification of
Bryan's ideas. I presented the tree pre-traversed -
i.e., flattened, like Bryan, and also used his predicates.
But I used ListT to provide the laziness instead of
unsafe IO.

My second proposal is to present the entire tree inside
a lazy monad transformer. While the internal plumbing
is slightly more complex, I think it will provide the most
natural and convenient interface for the end user
(who needs not understand all that monad stuff).

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