module System.FilePath.FilePather.Find
(
Find(..)
, findi
) where
import Control.Monad.Identity
import Control.Monad.Trans.Identity
import Control.Comonad
import System.FilePath
import System.FilePath.FilePather.RecursePredicate
import System.FilePath.FilePather.FilterPredicate
import System.FilePath.FilePather.FileType
import System.Directory
class Find f where
find ::
FilterPredicateT f
-> RecursePredicateT f
-> FilePath
-> IO [FilePath]
findHere ::
FilterPredicateT f
-> RecursePredicateT f
-> IO [FilePath]
findHere f r =
getCurrentDirectory >>= find f r
instance Find Identity where
find f' r' =
let find' base p =
let f =
runFilterPredicateT f'
r =
runRecursePredicateT r'
z ::
FilePath
z =
if null base then p else base </> p
keep ::
Bool
-> [FilePath]
-> [FilePath]
keep u =
if u then (z:) else id
rkeep ::
Bool
-> [FilePath]
-> IO [FilePath]
rkeep u d =
return (keep u d)
trkeep ::
FileType
-> IO [FilePath]
trkeep =
flip rkeep [] . runIdentity . f z
in do fe <- doesFileExist z
if fe
then
trkeep File
else
do de <- doesDirectoryExist z
if de
then
let (Identity k) = f z Directory
(Identity l) = r z
in if l
then
do t <- getDirectoryContents z
u <- forM (filter (`notElem` [".", ".."]) t) (find f' r' . (z </>))
rkeep k (concat u)
else
rkeep k []
else
trkeep Unknown
in find' []
findi ::
FilterPredicate
-> RecursePredicate
-> FilePath
-> IO [FilePath]
findi =
find
instance Find IO where
find f' r' =
let find' base p =
let f =
runFilterPredicateT f'
r =
runRecursePredicateT r'
z ::
FilePath
z =
if null base then p else base </> p
keep ::
Bool
-> [FilePath]
-> [FilePath]
keep u =
if u then (z:) else id
rkeep ::
Bool
-> [FilePath]
-> IO [FilePath]
rkeep u d =
return (keep u d)
trkeep ::
FileType
-> IO [FilePath]
trkeep t =
f z t >>= flip rkeep []
in do fe <- doesFileExist z
if fe
then
trkeep File
else
do de <- doesDirectoryExist z
if de
then
do k <- f z Directory
l <- r z
if l
then
do t <- getDirectoryContents z
u <- forM (filter (`notElem` [".", ".."]) t) (find f' r' . (z </>))
rkeep k (concat u)
else
rkeep k []
else
trkeep Unknown
in find' []
instance Comonad f => Find (IdentityT f) where
find f r =
find (filterPredicateT $ \p -> Identity . extract . runFilterPredicateT f p) (recursePredicateT $ Identity . extract . runRecursePredicateT r)