Skip to content

Commit ad08358

Browse files
documentation fixes; fix bugs in extractM_; change in the semantics of filter
1 parent 17d55e3 commit ad08358

File tree

2 files changed

+34
-25
lines changed

2 files changed

+34
-25
lines changed

filesystem-trees.cabal

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Name: filesystem-trees
2-
Version: 0.0
2+
Version: 0.1
33
Synopsis: Recursively manipulate and traverse filesystems as lazy rose trees.
44
Cabal-Version: >= 1.10
55
License: BSD3
@@ -16,12 +16,12 @@ library
1616
if impl(ghc >= 7.2)
1717
default-extensions: Trustworthy
1818
build-depends: base == 4.*
19-
, directory
20-
, filepath
21-
, unix
19+
, directory >= 1.1 && < 1.2
20+
, filepath >= 1.0 && < 2.0
21+
, unix >= 2.0 && < 3.0
2222
, containers >= 0.1 && < 0.6
23-
, data-lens
24-
, dlist
25-
, mtl
23+
, data-lens >= 2.0.1 && < 3.0
24+
, dlist >= 0.2 && < 1.0
25+
, mtl >= 1.0 && < 3.0
2626
, cond >= 0.3 && < 0.5
2727
exposed-modules: System.File.Tree

src/System/File/Tree.hs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,11 @@ type FSForest = [FSTree]
118118
mkFSTree :: FilePath -> FSForest -> FSTree
119119
mkFSTree a = FSTree . Node a . mapToTree
120120

121+
-- |Efficiently maps 'FSTree' over a list. This is more efficient than map FSTree
121122
mapFSTree :: Forest FilePath -> FSForest
122123
mapFSTree = unsafeCoerce
123124

125+
-- |Efficiently maps toTree over a list. This is more effficient than map toTree
124126
mapToTree :: FSForest -> Forest FilePath
125127
mapToTree = unsafeCoerce
126128

@@ -236,34 +238,41 @@ mapM_ :: Monad m => (FilePath -> m b) -> FSTree -> m ()
236238
mapM_ f t = mapM f t >> return ()
237239

238240
-- |Applies a predicate to each path name in a filesystem forest, and removes
239-
-- all unsuccessful paths from the result.
240-
--
241-
-- Note that if a directory fails the predicate test, then all of its children are
242-
-- removed as well.
241+
-- all unsuccessful paths from the result. If a directory fails the predicate test,
242+
-- then it will only be removed if all of its children also fail the test
243243
filter :: (FilePath -> Bool) -> FSForest -> FSForest
244-
filter p = fst . extract p
244+
filter p = runIdentity . filterM (return . p)
245245

246246
-- |Find all sub-forests within a forest that match the given predicate.
247247
find :: (FilePath -> Bool) -> FSForest -> FSForest
248-
find p = snd . extract (not . p)
248+
find p = snd . extract p
249249

250-
-- |A generalization of 'find' and 'filter'. The first element of the result
251-
-- represents the forest after filtering with the given predicate, and the second
252-
-- element is a list of trees that didn't match the predicate. This could be useful
253-
-- if you want to handle certain directories specially from others within a
250+
-- |A generalization of 'find'. The first element of the result
251+
-- represents the forest after removing all subtrees that match the given predicate,
252+
-- and the second element is a list of trees that matched. This could be useful if
253+
-- you want to handle certain directories specially from others within a
254254
-- sub-filesystem.
255255
extract :: (FilePath -> Bool) -> FSForest -> (FSForest, FSForest)
256256
extract p = runIdentity . extractM (return . p)
257257

258258
-- |Monadic 'filter'.
259259
filterM :: Monad m =>
260260
(FilePath -> m Bool) -> FSForest -> m FSForest
261-
filterM p = liftM fst . extractM p
261+
filterM p = foldrM (filter' . prependPaths) []
262+
where filter' (Node path cs) ts =
263+
ifM (p path)
264+
(liftM ((:ts) . mkFSTree path) $ foldrM filter' [] cs)
265+
(do
266+
cs' <- foldrM filter' [] $ cs
267+
return $ case cs' of
268+
[] -> ts
269+
_ -> mkFSTree path cs' : ts
270+
)
262271

263272
-- |Monadic 'find'.
264273
findM :: Monad m =>
265274
(FilePath -> m Bool) -> FSForest -> m FSForest
266-
findM p = liftM snd . extractM (notM . p)
275+
findM p = liftM snd . extractM p
267276

268277
-- |Monadic 'extract'.
269278
extractM :: Monad m =>
@@ -276,13 +285,13 @@ extractM_ p = foldrM extract' ([], DL.empty) . P.map prependPaths
276285
where
277286
extract' t@(Node path cs) (ts, es)
278287
= ifM (p path)
279-
( do
280-
(cs', es') <- foldrM extract' (ts, es) cs
281-
let t' = mkFSTree path cs'
282-
return (t' : ts, es' `append` es)
283-
)
284288
(
285-
return (ts, FSTree t `cons` es)
289+
return (ts, FSTree t `cons` es)
290+
)
291+
(do
292+
(cs', es') <- foldrM extract' ([], DL.empty) cs
293+
let t' = mkFSTree path cs'
294+
return (t' : ts, es' `append` es)
286295
)
287296

288297
-- |Truncate a tree to a given maximum level, where root is level 0.

0 commit comments

Comments
 (0)