Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell98 |
- newtype CondT a m b = CondT {}
- type Cond a = CondT a Identity
- runCondT :: Monad m => CondT a m b -> a -> m (Maybe b)
- runCond :: Cond a b -> a -> Maybe b
- applyCondT :: Monad m => a -> CondT a m b -> m ((Maybe b, Maybe (CondT a m b)), a)
- applyCond :: a -> Cond a b -> ((Maybe b, Maybe (Cond a b)), a)
- guardM :: Monad m => m Bool -> CondT a m ()
- guard_ :: Monad m => (a -> Bool) -> CondT a m ()
- guardM_ :: Monad m => (a -> m Bool) -> CondT a m ()
- apply :: Monad m => (a -> m (Maybe b)) -> CondT a m b
- consider :: Monad m => (a -> m (Maybe (b, a))) -> CondT a m b
- matches :: Monad m => CondT a m b -> CondT a m Bool
- if_ :: Monad m => CondT a m r -> CondT a m b -> CondT a m b -> CondT a m b
- when_ :: Monad m => CondT a m r -> CondT a m () -> CondT a m ()
- unless_ :: Monad m => CondT a m r -> CondT a m () -> CondT a m ()
- or_ :: Monad m => [CondT a m b] -> CondT a m b
- and_ :: Monad m => [CondT a m b] -> CondT a m ()
- not_ :: Monad m => CondT a m b -> CondT a m ()
- ignore :: Monad m => CondT a m b
- norecurse :: Monad m => CondT a m ()
- prune :: Monad m => CondT a m b
- recurse :: Monad m => CondT a m b -> CondT a m b
- test :: Monad m => a -> CondT a m b -> m Bool
- newtype CondEitherT a m b = 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
- toCondT :: Monad m => CondEitherT a m b -> CondT a m b
Documentation
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.
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
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
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
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.
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
.