module System.FilePath.FilePather.Find
(
Find(..)
) where
import Control.Monad.Identity
import Control.Monad.Trans.Identity
import Control.Comonad
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]
instance Find Identity where
find f' r' p =
let f =
runFilterPredicateT f'
r =
runRecursePredicateT r'
keep ::
Bool
-> [FilePath]
-> [FilePath]
keep u =
if u then (p:) else id
rkeep ::
[FilePath]
-> Bool
-> IO [FilePath]
rkeep d u =
return (keep u d)
trkeep ::
FileType
-> IO [FilePath]
trkeep t =
rkeep [] $ runIdentity (f p t)
in do fe <- doesFileExist p
if fe
then
trkeep File
else
do de <- doesDirectoryExist p
if de
then
let (Identity k) = f p Directory
(Identity l) = r p
in if l
then
do t <- getDirectoryContents p
u <- liftM concat $ forM (filter (`notElem` [".", ".."]) t) (find f' r')
rkeep u k
else
rkeep [] k
else
trkeep Unknown
instance Find IO where
find f' r' p =
let f =
runFilterPredicateT f'
r =
runRecursePredicateT r'
keep ::
Bool
-> [FilePath]
-> [FilePath]
keep u =
if u then (p:) else id
rkeep ::
[FilePath]
-> Bool
-> IO [FilePath]
rkeep d u =
return (keep u d)
trkeep ::
FileType
-> IO [FilePath]
trkeep t =
f p t >>= rkeep []
in do fe <- doesFileExist p
if fe
then
trkeep File
else
do de <- doesDirectoryExist p
if de
then
do k <- f p Directory
l <- r p
if l
then
do t <- getDirectoryContents p
u <- liftM concat $ forM (filter (`notElem` [".", ".."]) t) (find f' r')
rkeep u k
else
rkeep [] k
else
trkeep Unknown
instance Comonad f => Find (IdentityT f) where
find f r =
find (filterPredicateT $ \p -> Identity . extract . runFilterPredicateT f p) (recursePredicateT $ Identity . extract . runRecursePredicateT r)