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

Safe HaskellSafe
LanguageHaskell2010

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

Instances

MonadBase b m => MonadBase b (CondT a m) Source # 

Methods

liftBase :: b α -> CondT a m α #

MonadBaseControl b m => MonadBaseControl b (CondT r m) Source # 

Associated Types

type StM (CondT r m :: * -> *) a :: * #

Methods

liftBaseWith :: (RunInBase (CondT r m) b -> b a) -> CondT r m a #

restoreM :: StM (CondT r m) a -> CondT r m a #

Monad m => MonadReader a (CondT a m) Source # 

Methods

ask :: CondT a m a #

local :: (a -> a) -> CondT a m a -> CondT a m a #

reader :: (a -> a) -> CondT a m a #

Monad m => MonadState a (CondT a m) Source # 

Methods

get :: CondT a m a #

put :: a -> CondT a m () #

state :: (a -> (a, a)) -> CondT a m a #

MonadTrans (CondT a) Source # 

Methods

lift :: Monad m => m a -> CondT a m a #

MFunctor (CondT a) Source # 

Methods

hoist :: Monad m => (forall b. m b -> n b) -> CondT a m b -> CondT a n b #

Monad m => Monad (CondT a m) Source # 

Methods

(>>=) :: CondT a m a -> (a -> CondT a m b) -> CondT a m b #

(>>) :: CondT a m a -> CondT a m b -> CondT a m b #

return :: a -> CondT a m a #

fail :: String -> CondT a m a #

Monad m => Functor (CondT a m) Source # 

Methods

fmap :: (a -> b) -> CondT a m a -> CondT a m b #

(<$) :: a -> CondT a m b -> CondT a m a #

Monad m => Applicative (CondT a m) Source # 

Methods

pure :: a -> CondT a m a #

(<*>) :: CondT a m (a -> b) -> CondT a m a -> CondT a m b #

(*>) :: CondT a m a -> CondT a m b -> CondT a m b #

(<*) :: CondT a m a -> CondT a m b -> CondT a m a #

Monad m => Alternative (CondT a m) Source # 

Methods

empty :: CondT a m a #

(<|>) :: CondT a m a -> CondT a m a -> CondT a m a #

some :: CondT a m a -> CondT a m [a] #

many :: CondT a m a -> CondT a m [a] #

Monad m => MonadPlus (CondT a m) Source # 

Methods

mzero :: CondT a m a #

mplus :: CondT a m a -> CondT a m a -> CondT a m a #

MonadIO m => MonadIO (CondT a m) Source # 

Methods

liftIO :: IO a -> CondT a m a #

MonadThrow m => MonadThrow (CondT a m) Source # 

Methods

throwM :: Exception e => e -> CondT a m a #

MonadCatch m => MonadCatch (CondT a m) Source # 

Methods

catch :: Exception e => CondT a m a -> (e -> CondT a m a) -> CondT a m a #

MonadMask m => MonadMask (CondT a m) Source # 

Methods

mask :: ((forall b. CondT a m b -> CondT a m b) -> CondT a m b) -> CondT a m b #

uninterruptibleMask :: ((forall b. CondT a m b -> CondT a m b) -> CondT a m b) -> CondT a m b #

Show (CondT a m b) Source # 

Methods

showsPrec :: Int -> CondT a m b -> ShowS #

show :: CondT a m b -> String #

showList :: [CondT a m b] -> ShowS #

(Monad m, Semigroup b) => Semigroup (CondT a m b) Source # 

Methods

(<>) :: CondT a m b -> CondT a m b -> CondT a m b #

sconcat :: NonEmpty (CondT a m b) -> CondT a m b #

stimes :: Integral b => b -> CondT a m b -> CondT a m b #

(Monad m, Monoid b) => Monoid (CondT a m b) Source # 

Methods

mempty :: CondT a m b #

mappend :: CondT a m b -> CondT a m b -> CondT a m b #

mconcat :: [CondT a m b] -> CondT a m b #

type StM (CondT r m) a Source # 
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.