apfelmus' interface degustation - System.FilePath.Find
bos at serpentine.com
Fri Jun 29 20:26:35 EDT 2007
> b) Making (FindClause a) a mere type synonym of (FileInfo -> a)
> has the benefit that the user can choose whether he wants to use
> monads or applicative functors via the respective instances
> or whether he does not.
That's where I had started out, as a matter of fact.
> or for general applicative functors as
> (||) <$> ((== ".hs") <$> extension) <*> ((== ".lhs") <$> extension)
I don't find that very readable, I must confess.
> Maybe unsafePerformIO is the best solution, because you may safely close
> the file after having evaluated
> predicate (unsafePerformIO $ hGetContents handle) (fileinfo)
> to weak head normal form, i.e. True or False. I think it fits perfectly.
unsafeInterleaveIO $ readFile fileName
ought to be better, because it will not try to open the file unless the
predicate actually inspects it, and opening files is expensive. But it
will also not close the file until a finalizer kicks in. A tidier
approach might be:
maybeH <- newIORef Nothing
contents <- unsafeInterleaveIO $ do
h <- openFile fileName ReadMode
writeIORef maybeH (Just h)
let result = predicate contents
result `seq` readIORef maybeH >>= maybe (return ()) hClose
That's a little cumbersome, but very appealing from the perspective of a
user of the library. Unfortunately, it looks to me like it's not very
safe; see below.
> System.FilePath.Find.fold gives you both file status and file path but
> the ought-to-be equivalent approach of using foldl' on the list returned
> by find only gives the file path but no file status. So, the suggestion
> is to make find return a list of FileInfo
Let me pass an idea by you. There's a problem with augmenting FileInfo
to potentially cause IO to occur as above (both with your original
suggestion and my changes), no? We lose the ability to control when a
file might be opened, and when it ought to be closed.
If that were the case, the fold interface would have the same problem,
if it decided for some reason to sock away FileInfo values in an
accumulator and work on them after the fold had completed.
> Of course, this leads to the question whether find should be factored
> even more into generate & prune
> find r p dir = map filepath . filter p . directoryWalk r dir
> with the intention that System.FilePath.Find only exports directoryWalk.
That's a nice idea, but subject to the same problems as the fold
interface would be if we added file contents to the interface.
Your other observations regarding making a directory tree abstract, and
instances of some of our favourite typeclasses, are very appealing. Now
if only I could figure out a clean way to avoid bad things happening in
the presence of that user-friendly IO code...
More information about the Libraries