@@ -27,11 +27,15 @@ module Streamly.Coreutils.FileTest
2727
2828 -- * Boolean Operations
2929 , neg
30+ , negM
3031 , and
32+ , andM
3133 , or
34+ , orM
3235
3336 -- * Running Predicates
3437 , test
38+ , testM
3539 , testFD
3640
3741 -- * Predicates
@@ -93,6 +97,9 @@ instance Monoid (Predicate a) where
9397
9498#endif
9599
100+ -- $setup
101+ -- >>> import Prelude hiding (or, and)
102+
96103-- Naming Notes: Named FileTest rather than "Test" to be more explicit and
97104-- specific. The command can also be named fileTest or testFile.
98105
@@ -109,13 +116,27 @@ or :: FileTest -> FileTest -> FileTest
109116FileTest (Predicate p) `or` FileTest (Predicate q) =
110117 FileTest (Predicate $ \ a -> p a || q a)
111118
119+ -- | Like `or` but for monadic predicates.
120+ --
121+ -- >>> orM t1 t2 = pure or <*> t1 <*> t2
122+ --
123+ orM :: IO FileTest -> IO FileTest -> IO FileTest
124+ orM t1 t2 = pure or <*> t1 <*> t2
125+
112126-- | A boolean @and@ function for 'FileTest' predicates.
113127--
114128-- >>> and = (<>)
115129--
116130and :: FileTest -> FileTest -> FileTest
117131and = (<>)
118132
133+ -- | Like `and` but for monadic predicates.
134+ --
135+ -- >>> andM t1 t2 = pure and <*> t1 <*> t2
136+ --
137+ andM :: IO FileTest -> IO FileTest -> IO FileTest
138+ andM t1 t2 = pure and <*> t1 <*> t2
139+
119140-- Naming notes: I would prefer to use "not" instead of "neg" but this has to
120141-- be used unqualified to remain short for common use and prelude "not" is also
121142-- very common so we do not want to conflict with that.
@@ -135,6 +156,13 @@ and = (<>)
135156neg :: FileTest -> FileTest
136157neg (FileTest (Predicate p)) = FileTest (Predicate $ \ a -> Prelude. not (p a))
137158
159+ -- | Like `neg` but for monadic predicates.
160+ --
161+ -- >>> negM = fmap neg
162+ --
163+ negM :: IO FileTest -> IO FileTest
164+ negM = fmap neg
165+
138166-- XXX Use a byte array instead of string filepath.
139167--
140168-- | Run a predicate on a 'FilePath'. Returns False if the path does not exist.
@@ -154,8 +182,15 @@ test path (FileTest (Predicate f)) =
154182
155183 eatENOENT e = if isENOENT e then return False else throwIO e
156184
185+ -- | Like 'test' but for a monadic predicate.
186+ --
187+ -- >>> testM path t = test path =<< t
188+ --
189+ testM :: FilePath -> IO FileTest -> IO Bool
190+ testM path t = test path =<< t
191+
157192-- XXX Use Handle instead
158- -- | Run a predicate on an 'Fd' .
193+ -- | Like 'test' but uses a file descriptor instead of file path .
159194testFD :: Fd -> FileTest -> IO Bool
160195testFD fd (FileTest (Predicate f)) = Files. getFdStatus fd >>= return . f
161196
0 commit comments