-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Evaluate and display trees of predicates
--   
--   Build and evaluate trees of predicates. For example, you might build a
--   predicate of the type Int -&gt; Bool. You do this by assembling
--   several predicates into a tree. You can then verbosely evaluate this
--   tree, showing why a particular result is reached.
--   
--   prednote also provides modules to test several subjects against a
--   given predicate, and to parse infix or RPN expressions into a tree of
--   predicates.
@package prednote
@version 0.36.0.4

module Prednote.Core

-- | Predicates. Is an instance of <a>Contravariant</a>, which allows you
--   to change the type using <a>contramap</a>. Though the constructor is
--   exported, ordinarily you shouldn't need to use it; other functions in
--   this module create <a>PredM</a> and manipulate them as needed.
--   
--   The <tt>f</tt> type variable is an arbitrary context; ordinarily this
--   type will be an instance of <a>Monad</a>, and some of the bindings in
--   this module require this. That allows you to run predicate
--   computations that run in some sort of context, allowing you to perform
--   IO, examine state, or whatever. If you only want to do pure
--   computations, just use the <a>Pred</a> type synonym.
newtype PredM f a
PredM :: (a -> f Result) -> PredM f a
[runPredM] :: PredM f a -> (a -> f Result)

-- | Predicates that do not run in any context.
type Pred = PredM Identity

-- | Creates a new <a>Pred</a> that do not run in any context. In
--   <tt>predicate cond f</tt>, <tt>cond</tt> describes the condition,
--   while <tt>f</tt> gives the predicate function. For example, if
--   <tt>f</tt> is <tt>(&gt; 5)</tt>, then <tt>cond</tt> might be <tt>"is
--   greater than 5"</tt>.
predicate :: (a -> (Bool, Value, Condition)) -> Pred a

-- | Creates a new <a>PredM</a> that run in some arbitrary context. In
--   <tt>predicateM cond f</tt>, <tt>cond</tt> describes the condition,
--   while <tt>f</tt> gives the predicate function. For example, if
--   <tt>f</tt> is <tt>(&gt; 5)</tt>, then <tt>cond</tt> might be <tt>"is
--   greater than 5"</tt>.
predicateM :: Functor f => (a -> f (Bool, Value, Condition)) -> PredM f a

-- | Like <a>contramap</a> but allows the mapping function to run in a
--   monad.
contramapM :: Monad m => (a -> m b) -> PredM m b -> PredM m a

-- | And. Returns <a>True</a> if both argument <a>Pred</a> return
--   <a>True</a>. Is lazy in its second argment; if the first argument
--   returns <a>False</a>, the second is ignored.
(&&&) :: Monad m => PredM m a -> PredM m a -> PredM m a
infixr 3 &&&

-- | Or. Returns <a>True</a> if either argument <a>Pred</a> returns
--   <a>True</a>. Is lazy in its second argument; if the first argument
--   returns <a>True</a>, the second argument is ignored.
(|||) :: Monad m => PredM m a -> PredM m a -> PredM m a
infixr 2 |||

-- | Negation. Returns <a>True</a> if the argument <a>Pred</a> returns
--   <a>False</a>.
not :: Functor m => PredM m a -> PredM m a

-- | Uses the appropriate <a>Pred</a> depending on the <a>Either</a> value.
--   In <tt><a>test</a> (<a>switch</a> l r) e</tt>, the resulting
--   <a>Pred</a> returns the result of <tt>l</tt> if <tt>e</tt> is
--   <a>Left</a> or the result of <tt>r</tt> if <tt>e</tt> is <a>Right</a>.
--   Is lazy, so the the argument <a>Pred</a> that is not used is ignored.
switch :: PredM m a -> PredM m b -> PredM m (Either a b)

-- | Like <a>any</a>; is <a>True</a> if any of the list items are
--   <a>True</a>. An empty list returns <a>False</a>. Is lazy; will stop
--   processing if it encounters a <a>True</a> item.
any :: (Monad m, Applicative m) => PredM m a -> PredM m [a]

-- | Like <a>all</a>; is <a>True</a> if none of the list items is
--   <a>False</a>. An empty list returns <a>True</a>. Is lazy; will stop
--   processing if it encouters a <a>False</a> item.
all :: (Monad m, Applicative m) => PredM m a -> PredM m [a]

-- | Create a <a>Pred</a> for <a>Maybe</a>.
maybe :: Applicative m => Bool -> PredM m a -> PredM m (Maybe a)

-- | Adds descriptive text to a <a>Pred</a>. Gives useful information for
--   the user. The label is added to the top <a>Pred</a> in the tree; any
--   existing labels are also retained. Labels that were added last will be
--   printed first. For an example of this, see the source code for
--   <a>any</a> and <a>all</a>.
addLabel :: Functor f => [Chunk Text] -> PredM f a -> PredM f a

-- | Always returns <a>True</a>
true :: Applicative f => PredM f a

-- | Always returns <a>False</a>
false :: Applicative f => PredM f a

-- | Always returns its argument
same :: Applicative f => PredM f Bool

-- | Runs a <a>Pred</a> against a value, without a context.
test :: Pred a -> a -> Bool

-- | Runs a <a>Pred</a> against a value.
testM :: Functor f => PredM f a -> a -> f Bool

-- | Runs pure <a>Pred</a> computations.
runPred :: Pred a -> a -> Result
verboseTest :: Pred a -> a -> ([Chunk Text], Bool)

-- | Like <a>verboseTest</a>, but results are printed to standard output.
--   Primarily for use in debugging or in a REPL.
verboseTestStdout :: Pred a -> a -> IO Bool

-- | Describes the condition; for example, for a <tt><a>Pred</a>
--   <a>Int</a></tt>, this might be <tt>is greater than 5</tt>; for a
--   <tt><a>Pred</a> <a>String</a></tt>, this might be <tt>begins with
--   "Hello"</tt>.
newtype Condition
Condition :: [Chunk Text] -> Condition

-- | Stores the representation of a value.
newtype Value
Value :: [Chunk Text] -> Value

-- | Gives additional information about a particular <a>Pred</a> to aid the
--   user when viewing the output.
newtype Label
Label :: [Chunk Text] -> Label

-- | Any type that is accompanied by a set of labels.
data Labeled a
Labeled :: [Label] -> a -> Labeled a

-- | A <a>Pred</a> that returned <a>True</a>
data Passed

-- | A <a>Pred</a> created with <a>predicate</a>
PTerminal :: Value -> Condition -> Passed

-- | A <a>Pred</a> created with <a>&amp;&amp;&amp;</a>
PAnd :: (Labeled Passed) -> (Labeled Passed) -> Passed

-- | A <a>Pred</a> created with <a>|||</a>
POr :: (Either (Labeled Passed) (Labeled Failed, Labeled Passed)) -> Passed

-- | A <a>Pred</a> created with <a>not</a>
PNot :: (Labeled Failed) -> Passed

-- | A <a>Pred</a> that returned <a>False</a>
data Failed

-- | A <a>Pred</a> created with <a>predicate</a>
FTerminal :: Value -> Condition -> Failed

-- | A <a>Pred</a> created with <a>&amp;&amp;&amp;</a>
FAnd :: (Either (Labeled Failed) (Labeled Passed, Labeled Failed)) -> Failed

-- | A <a>Pred</a> created with <a>|||</a>
FOr :: (Labeled Failed) -> (Labeled Failed) -> Failed

-- | A <a>Pred</a> created with <a>not</a>
FNot :: (Labeled Passed) -> Failed

-- | The result of processing a <a>Pred</a>.
newtype Result
Result :: (Labeled (Either Failed Passed)) -> Result

-- | Returns whether this <a>Result</a> failed or passed.
splitResult :: Result -> Either (Labeled Failed) (Labeled Passed)

-- | Obtain a list of <a>Chunk</a> describing the evaluation process.
resultToChunks :: Result -> [Chunk Text]

-- | Obtain a list of <a>Chunk</a> describing the evaluation process.
passedToChunks :: Int -> Labeled Passed -> [Chunk Text]

-- | Obtain a list of <a>Chunk</a> describing the evaluation process.
failedToChunks :: Int -> Labeled Failed -> [Chunk Text]
instance GHC.Show.Show Prednote.Core.Result
instance GHC.Classes.Ord Prednote.Core.Result
instance GHC.Classes.Eq Prednote.Core.Result
instance GHC.Show.Show Prednote.Core.Passed
instance GHC.Classes.Ord Prednote.Core.Passed
instance GHC.Classes.Eq Prednote.Core.Passed
instance GHC.Show.Show Prednote.Core.Failed
instance GHC.Classes.Ord Prednote.Core.Failed
instance GHC.Classes.Eq Prednote.Core.Failed
instance GHC.Show.Show a => GHC.Show.Show (Prednote.Core.Labeled a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Prednote.Core.Labeled a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Prednote.Core.Labeled a)
instance GHC.Show.Show Prednote.Core.Label
instance GHC.Classes.Ord Prednote.Core.Label
instance GHC.Classes.Eq Prednote.Core.Label
instance GHC.Show.Show Prednote.Core.Value
instance GHC.Classes.Ord Prednote.Core.Value
instance GHC.Classes.Eq Prednote.Core.Value
instance GHC.Show.Show Prednote.Core.Condition
instance GHC.Classes.Ord Prednote.Core.Condition
instance GHC.Classes.Eq Prednote.Core.Condition
instance GHC.Base.Monoid Prednote.Core.Condition
instance GHC.Base.Monoid Prednote.Core.Value
instance GHC.Base.Monoid Prednote.Core.Label
instance GHC.Base.Functor Prednote.Core.Labeled
instance GHC.Show.Show (Prednote.Core.PredM f a)
instance Data.Functor.Contravariant.Contravariant (Prednote.Core.PredM f)


-- | Postfix, or RPN, expression parsing.
--   
--   This module parses RPN expressions where the operands are predicates
--   and the operators are one of <tt>and</tt>, <tt>or</tt>, or
--   <tt>not</tt>, where <tt>and</tt> and <tt>or</tt> are binary and
--   <tt>not</tt> is unary.
module Prednote.Expressions.RPN
data RPNToken f a
TokOperand :: (PredM f a) -> RPNToken f a
TokOperator :: Operator -> RPNToken f a
data Operator
OpAnd :: Operator
OpOr :: Operator
OpNot :: Operator
pushOperand :: PredM f a -> [PredM f a] -> [PredM f a]
pushOperator :: (Monad m, Functor m) => Operator -> [PredM m a] -> Either Text [PredM m a]
pushToken :: (Functor f, Monad f) => [PredM f a] -> RPNToken f a -> Either Text [PredM f a]

-- | Parses an RPN expression and returns the resulting <tt>Pred</tt>.
--   Fails if there are no operands left on the stack or if there are
--   multiple operands left on the stack; the stack must contain exactly
--   one operand in order to succeed.
parseRPN :: (Functor m, Monad m) => Foldable f => f (RPNToken m a) -> Either Text (PredM m a)
instance GHC.Show.Show Prednote.Expressions.RPN.Operator

module Prednote.Expressions.Infix
data InfixToken f a
TokRPN :: (RPNToken f a) -> InfixToken f a
TokParen :: Paren -> InfixToken f a
data Paren
Open :: Paren
Close :: Paren

-- | Creates an RPN expression from an infix one. Fails only if there are
--   mismatched parentheses. It is possible to create a nonsensical RPN
--   expression; the RPN parser must catch this.
createRPN :: Foldable f => f (InfixToken m a) -> Maybe [RPNToken m a]


-- | Handles parsing of both infix and RPN <a>Pred</a> expressions.
module Prednote.Expressions

-- | Is this an infix or RPN expression?
data ExprDesc
Infix :: ExprDesc
RPN :: ExprDesc
type Error = Text

-- | A single type for both RPN tokens and infix tokens.
data Token m a

-- | Creates Operands from <a>Pred</a>.
operand :: PredM m a -> Token m a

-- | The And operator
opAnd :: Token m a

-- | The Or operator
opOr :: Token m a

-- | The Not operator
opNot :: Token m a

-- | Open parentheses
openParen :: Token m a

-- | Close parentheses
closeParen :: Token m a

-- | Parses expressions. Fails if the expression is nonsensical in some way
--   (for example, unbalanced parentheses, parentheses in an RPN
--   expression, or multiple stack values remaining.) Works by first
--   changing infix expressions to RPN ones.
parseExpression :: (Functor m, Monad m) => ExprDesc -> [Token m a] -> Either Error (PredM m a)
instance GHC.Show.Show Prednote.Expressions.ExprDesc
instance GHC.Classes.Eq Prednote.Expressions.ExprDesc

module Prednote.Comparisons

-- | Build a Pred that compares items. The idea is that the item on the
--   right hand side is baked into the <a>Pred</a> and that the <a>Pred</a>
--   compares this single right-hand side to each left-hand side item.
compareBy :: Show a => Text -> (a -> Ordering) -> Ordering -> Pred a

-- | Overloaded version of <a>compareBy</a>.
compare :: (Show a, Ord a) => a -> Ordering -> Pred a

-- | Builds a <a>Pred</a> that tests items for equality.
equalBy :: Show a => Text -> (a -> Bool) -> Pred a

-- | Overloaded version of <a>equalBy</a>.
equal :: (Eq a, Show a) => a -> Pred a

-- | Builds a <a>Pred</a> for items that might fail to return a comparison.
compareByMaybe :: Show a => Text -> (a -> Maybe Ordering) -> Ordering -> Pred a
greater :: (Show a, Ord a) => a -> Pred a
less :: (Show a, Ord a) => a -> Pred a
greaterEq :: (Show a, Ord a) => a -> Pred a
lessEq :: (Show a, Ord a) => a -> Pred a
notEq :: (Show a, Eq a) => a -> Pred a
greaterBy :: Show a => Text -> (a -> Ordering) -> Pred a
lessBy :: Show a => Text -> (a -> Ordering) -> Pred a
greaterEqBy :: Show a => Text -> (a -> Ordering) -> Pred a
lessEqBy :: Show a => Text -> (a -> Ordering) -> Pred a
notEqBy :: Show a => Text -> (a -> Bool) -> Pred a

-- | Build a Pred that compares items. The idea is that the item on the
--   right hand side is baked into the <a>Pred</a> and that the <a>Pred</a>
--   compares this single right-hand side to each left-hand side item.
compareByM :: (Show a, Functor f) => Text -> (a -> f Ordering) -> Ordering -> PredM f a

-- | Builds a <a>Pred</a> that tests items for equality.
equalByM :: (Show a, Functor f) => Text -> (a -> f Bool) -> PredM f a

-- | Builds a <a>Pred</a> for items that might fail to return a comparison.
compareByMaybeM :: (Functor f, Show a) => Text -> (a -> f (Maybe Ordering)) -> Ordering -> PredM f a
greaterByM :: (Show a, Functor f) => Text -> (a -> f Ordering) -> PredM f a
lessByM :: (Show a, Functor f) => Text -> (a -> f Ordering) -> PredM f a
greaterEqByM :: (Functor f, Monad f, Show a) => Text -> (a -> f Ordering) -> PredM f a
lessEqByM :: (Functor f, Monad f, Show a) => Text -> (a -> f Ordering) -> PredM f a
notEqByM :: (Functor f, Show a) => Text -> (a -> f Bool) -> PredM f a

-- | Parses a string that contains text, such as <tt>&gt;=</tt>, which
--   indicates which comparer to use. Returns the comparer.
parseComparer :: (Monad f, Functor f) => Text -> (Ordering -> PredM f a) -> Maybe (PredM f a)


-- | Prednote - annotated predicates
--   
--   This module exports all the types and functions you will ordinarily
--   need. Many names clash with Prelude names, because these names made
--   the most sense. But I didn't make any clashing operators, as I'm not
--   that much of a masochist. So you will probably want to do something
--   like
--   
--   <pre>
--   import qualified Prednote as P
--   import Prednote ((|||), (&amp;&amp;&amp;))
--   </pre>
--   
--   For more documentation, first see <a>Prednote.Core</a>, and then
--   <a>Prednote.Comparisons</a> and then <a>Prednote.Expressions</a>.
module Prednote
