find-conduit-0.4.4: A file-finding conduit that allows user control over traversals.

Safe HaskellSafe-Inferred
LanguageHaskell98

Data.Cond

Contents

Synopsis

Documentation

newtype CondT a m b Source

CondT is a kind of StateT a (MaybeT m) b, which uses a special Result type instead of Maybe to express whether recursion should be performed from the item under consideration. This is used to build predicates that can guide recursive traversals.

Several different types may be promoted to CondT:

Bool
Using guard
m Bool
Using guardM
a -> Bool
Using guard_
a -> m Bool
Using guardM_
a -> m (Maybe b)
Using apply
a -> m (Maybe (b, a))
Using consider

Here is a trivial example:

flip runCondT 42 $ do
  guard_ even
  liftIO $ putStrLn "42 must be even to reach here"
  guard_ odd <|> guard_ even
  guard_ (== 42)

If CondT is executed using runCondT, it return a Maybe b if the predicate matched. It can also be run with applyCondT, which does case analysis on the Result, specifying how recursion should be performed from the given a value.

Constructors

CondT 

Fields

getCondT :: StateT a m (Result a m b)
 

Instances

Monad m => MonadState a (CondT a m) 
Monad m => MonadReader a (CondT a m) 
MonadBase b m => MonadBase b (CondT a m) 
MonadBaseControl b m => MonadBaseControl b (CondT r m) 
MonadTrans (CondT a) 
MFunctor (CondT a) 
Monad m => Alternative (CondT a m) 
Monad m => Monad (CondT a m) 
Monad m => Functor (CondT a m) 
Monad m => MonadPlus (CondT a m) 
Monad m => Applicative (CondT a m) 
MonadIO m => MonadIO (CondT a m) 
MonadThrow m => MonadThrow (CondT a m) 
MonadCatch m => MonadCatch (CondT a m) 
MonadMask m => MonadMask (CondT a m) 
Show (CondT a m b) 
(Monad m, Monoid b) => Monoid (CondT a m b) 
(Monad m, Semigroup b) => Semigroup (CondT a m b) 
type StM (CondT r m) a 

Executing CondT

runCondT :: Monad m => CondT a m b -> a -> m (Maybe b) Source

runCond :: Cond a b -> a -> Maybe b Source

applyCondT :: Monad m => a -> CondT a m b -> m ((Maybe b, Maybe (CondT a m b)), a) Source

Case analysis of applying a condition to an input value. The result is a pair whose first part is a pair of Maybes specifying if the input matched and if recursion is expected from this value, and whose second part is the (possibly) mutated input value.

applyCond :: a -> Cond a b -> ((Maybe b, Maybe (Cond a b)), a) Source

Case analysis of applying a pure condition to an input value. The result is a pair whose first part is a pair of Maybes specifying if the input matched and if recursion is expected from this value, and whose second part is the (possibly) mutated input value.

Promotions

guardM :: Monad m => m Bool -> CondT a m () Source

guard_ :: Monad m => (a -> Bool) -> CondT a m () Source

guardM_ :: Monad m => (a -> m Bool) -> CondT a m () Source

apply :: Monad m => (a -> m (Maybe b)) -> CondT a m b Source

consider :: Monad m => (a -> m (Maybe (b, a))) -> CondT a m b Source

Boolean logic

matches :: Monad m => CondT a m b -> CondT a m Bool Source

Return True or False depending on whether the given condition matches or not. This differs from simply stating the condition in that it itself always succeeds.

>>> flip runCond "foo.hs" $ matches (guard =<< asks (== "foo.hs"))
Just True
>>> flip runCond "foo.hs" $ matches (guard =<< asks (== "foo.hi"))
Just False

if_ :: Monad m => CondT a m r -> CondT a m b -> CondT a m b -> CondT a m b Source

A variant of ifM which branches on whether the condition succeeds or not. Note that if_ x is equivalent to ifM (matches x), and is provided solely for convenience.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> flip runCond "foo.hs" $ if_ good (return "Success") (return "Failure")
Just "Success"
>>> flip runCond "foo.hs" $ if_ bad (return "Success") (return "Failure")
Just "Failure"

when_ :: Monad m => CondT a m r -> CondT a m () -> CondT a m () Source

when_ is just like when, except that it executes the body if the condition passes, rather than based on a Bool value.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> flip runCond "foo.hs" $ when_ good ignore
Nothing
>>> flip runCond "foo.hs" $ when_ bad ignore
Just ()

unless_ :: Monad m => CondT a m r -> CondT a m () -> CondT a m () Source

when_ is just like when, except that it executes the body if the condition fails, rather than based on a Bool value.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> flip runCond "foo.hs" $ unless_ bad ignore
Nothing
>>> flip runCond "foo.hs" $ unless_ good ignore
Just ()

or_ :: Monad m => [CondT a m b] -> CondT a m b Source

Check whether at least one of the given conditions is true. This is a synonym for asum.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> flip runCond "foo.hs" $ or_ [bad, good]
Just ()
>>> flip runCond "foo.hs" $ or_ [bad]
Nothing

and_ :: Monad m => [CondT a m b] -> CondT a m () Source

Check that all of the given conditions are true. This is a synonym for sequence_.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> flip runCond "foo.hs" $ and_ [bad, good]
Nothing
>>> flip runCond "foo.hs" $ and_ [good]
Just ()

not_ :: Monad m => CondT a m b -> CondT a m () Source

not_ inverts the meaning of the given predicate.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> flip runCond "foo.hs" $ not_ bad >> return "Success"
Just "Success"
>>> flip runCond "foo.hs" $ not_ good >> return "Shouldn't reach here"
Nothing

Basic conditionals

ignore :: Monad m => CondT a m b Source

ignore ignores the current entry, but allows recursion into its descendents. This is the same as mzero.

norecurse :: Monad m => CondT a m () Source

norecurse prevents recursion into the current entry's descendents, but does not ignore the entry itself.

prune :: Monad m => CondT a m b Source

prune is a synonym for both ignoring an entry and its descendents. It is the same as ignore >> norecurse.

Helper functions

recurse :: Monad m => CondT a m b -> CondT a m b Source

recurse changes the recursion predicate for any child elements. For example, the following file-finding predicate looks for all *.hs files, but under any .git directory looks only for a file named config:

if_ (name_ ".git" >> directory)
    (ignore >> recurse (name_ "config"))
    (glob "*.hs")

NOTE: If this code had used recurse (glob "*.hs")) instead in the else case, it would have meant that .git is only looked for at the top-level of the search (i.e., the top-most element).

test :: Monad m => a -> CondT a m b -> m Bool Source

A specialized variant of runCondT that simply returns True or False.

>>> let good = guard_ (== "foo.hs") :: Cond String ()
>>> let bad  = guard_ (== "foo.hi") :: Cond String ()
>>> runIdentity $ test "foo.hs" $ not_ bad >> return "Success"
True
>>> runIdentity $ test "foo.hs" $ not_ good >> return "Shouldn't reach here"
False

Isomorphism with a stateful EitherT

newtype CondEitherT a m b Source

This type is for documentation only, and shows the isomorphism between CondT and CondEitherT. The reason for using Result is that it makes meaning of the constructors more explicit.

Constructors

CondEitherT (StateT a (EitherT (Maybe (Maybe (CondEitherT a m b))) m) (b, Maybe (Maybe (CondEitherT a m b)))) 

fromCondT :: Monad m => CondT a m b -> CondEitherT a m b Source

Witness one half of the isomorphism from CondT to CondEitherT.

toCondT :: Monad m => CondEitherT a m b -> CondT a m b Source

Witness the other half of the isomorphism from CondEitherT to CondT.