-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Simple applicative validation for product types, batteries included! -- -- Please see the README on GitHub at -- https://github.com/TotallyNotChase/valida#readme @package valida @version 0.1.0 -- | This module is re-exported by Valida. You probably don't need -- to import this. -- -- This module exports the primitive, as well as utility, -- ValidationRule combinators. As well as the orElse, -- andAlso, satisfyAny, and satisfyAll functions, -- and some more utilities. module Valida.Combinators -- | Build a rule that fails with given error if the given -- predicate succeeds. -- --
--   failureIf predc = failureUnless (not . predc)
--   
-- --

Examples

-- --
--   >>> runValidator (validate (failureIf (>0) "Positive")) 5
--   Failure ("Positive" :| [])
--   
--   >>> runValidator (validate (failureIf (>0) "Positive")) 0
--   Success 0
--   
--   >>> runValidator (validate (failureIf (>0) "Positive")) (-1)
--   Success (-1)
--   
failureIf :: (a -> Bool) -> e -> ValidationRule (NonEmpty e) a -- | Build a rule that fails with given error unless the given -- predicate succeeds. -- --
--   failureUnless predc = failureIf (not . predc)
--   
-- --

Examples

-- --
--   >>> runValidator (validate (failureUnless (>0) "NonPositive")) 5
--   Success 5
--   
--   >>> runValidator (validate (failureUnless (>0) "NonPositive")) 0
--   Failure ("NonPositive" :| [])
--   
--   >>> runValidator (validate (failureUnless (>0) "NonPositive")) (-1)
--   Failure ("NonPositive" :| [])
--   
failureUnless :: (a -> Bool) -> e -> ValidationRule (NonEmpty e) a -- | Like failureIf but uses Unit as the -- ValidationRule error type. -- --
--   failureIf' predc = failureUnless' (not . predc)
--   
-- --
--   label (const (err :| [])) (failureIf' predc) = failureIf predc err
--   
-- --

Examples

-- --
--   >>> runValidator (validate (failureIf' (>0))) 5
--   Failure ()
--   
--   >>> runValidator (validate (failureIf' (>0))) 0
--   Success 0
--   
--   >>> runValidator (validate (failureIf' (>0))) (-1)
--   Success (-1)
--   
failureIf' :: (a -> Bool) -> ValidationRule () a -- | Like failureUnless but uses Unit as the -- ValidationRule error type. -- --
--   failureUnless' predc = failureIf' (not . predc)
--   
-- --
--   label (const (err :| [])) (failureUnless' predc) = failureUnless predc err
--   
-- --

Examples

-- --
--   >>> runValidator (validate (failureUnless' (>0))) 5
--   Success 5
--   
--   >>> runValidator (validate (failureUnless' (>0))) 0
--   Failure ()
--   
--   >>> runValidator (validate (failureUnless' (>0))) (-1)
--   Failure ()
--   
failureUnless' :: (a -> Bool) -> ValidationRule () a -- | Build a rule that succeeds if given rule fails and vice versa. -- --

Examples

-- --
--   >>> let rule = negateRule "NonPositive" (failureIf (>0) "Positive")
--   
--   >>> runValidator (validate rule) 5
--   Success 5
--   
--   >>> runValidator (validate rule) 0
--   Failure "NonPositive"
--   
--   >>> runValidator (validate rule) (-1)
--   Failure "NonPositive"
--   
negateRule :: e -> ValidationRule e1 a -> ValidationRule e a -- | Like negateRule but uses Unit as the -- ValidationRule error type. negateRule' :: ValidationRule e a -> ValidationRule () a -- | Build a rule that only succeeds if both of the given -- rules succeed. The very first failure is yielded. -- -- This is the same as the semigroup operation (i.e (<>)) on -- ValidationRule. -- --
--   rule1 `andAlso` (rule2 `andAlso` rule3) = (rule1 `andAlso` rule2) `andAlso` rule3
--   
-- --
--   mempty `andAlso` rule = rule
--   
-- --
--   rule `andAlso` mempty = rule
--   
-- --

Examples

-- --
--   >>> let rule = failureIf (>0) "Positive" `andAlso` failureIf even "Even"
--   
--   >>> runValidator (validate rule) 5
--   Failure ("Positive" :| [])
--   
--   >>> runValidator (validate rule) (-2)
--   Failure ("Even" :| [])
--   
--   >>> runValidator (validate rule) (-1)
--   Success (-1)
--   
andAlso :: ValidationRule e a -> ValidationRule e a -> ValidationRule e a -- | A ValidationRule that always fails with supplied error. This is -- the identity of orElse (i.e (</>)). -- --
--   falseRule `orElse` rule = rule
--   
-- --
--   rule `orElse` falseRule = rule
--   
-- --

Examples

-- --
--   >>> runValidator (validate falseRule) 42
--   Failure ()
--   
falseRule :: Monoid e => ValidationRule e a -- | Build a rule that succeeds if either of the given rules -- succeed. If both fail, the errors are combined. -- --
--   rule1 `orElse` (rule2 `orElse` rule3) = (rule1 `orElse` rule2) `orElse` rule3
--   
-- --
--   falseRule e `orElse` rule = rule
--   
-- --
--   rule `orElse` falseRule e = rule
--   
-- --

Examples

-- --
--   >>> let rule = failureIf (>0) "Positive" `orElse` failureIf even "Even"
--   
--   >>> runValidator (validate rule) 5
--   Success 5
--   
--   >>> runValidator (validate rule) 4
--   Failure ("Positive" :| ["Even"])
--   
--   >>> runValidator (validate rule) 0
--   Success 0
--   
--   >>> runValidator (validate rule) (-1)
--   Success (-1)
--   
orElse :: Semigroup e => ValidationRule e a -> ValidationRule e a -> ValidationRule e a -- | Build a rule that only succeeds if all of the given -- rules succeed. The very first failure is yielded. -- --
--   satisfyAll = fold
--   
-- --
--   satisfyAll = foldl1 andAlso
--   
-- --
--   satisfyAll = foldr1 andAlso
--   
-- --
--   satisfyAll = foldl andAlso mempty
--   
-- --
--   satisfyAll = foldr andAlso mempty
--   
satisfyAll :: Foldable t => t (ValidationRule e a) -> ValidationRule e a -- | Build a rule that succeeds if any of the given rules -- succeed. If all fail, the errors are combined. -- --
--   satisfyAny = foldl1 orElse
--   
-- --
--   satisfyAny = foldr1 orElse
--   
-- --
--   satisfyAny = foldl orElse falseRule
--   
-- --
--   satisfyAny = foldr orElse falseRule
--   
satisfyAny :: (Foldable t, Semigroup e) => t (ValidationRule e a) -> ValidationRule e a -- | A synonym for orElse. Satisfies associativity law and hence -- forms a semigroup. () :: Semigroup e => ValidationRule e a -> ValidationRule e a -> ValidationRule e a infixr 5 -- | Build an any rule. -- --
--   atleastContains x = failureUnless (any x)
--   
atleastContains :: Foldable t => (a -> Bool) -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a minimum length (inclusive) rule. -- --
--   lengthAbove x = minLengthOf (x + 1)
--   
-- --
--   lengthAbove x = failureUnless ((>n) . length)
--   
lengthAbove :: Foldable t => Int -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a maximum length (inclusive) rule. -- --
--   lengthBelow x = maxLengthOf (x - 1)
--   
-- --
--   lengthBelow x = failureUnless ((<n) . length)
--   
lengthBelow :: Foldable t => Int -> e -> ValidationRule (NonEmpty e) (t a) -- | Build an inRange rule for length. -- --
--   lengthWithin (min, max) = minLengthOf min `andAlso` maxLengthOf max
--   
-- --
--   lengthWithin r = failureUnless (inRange r . length)
--   
lengthWithin :: Foldable t => (Int, Int) -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a maximum length (inclusive) rule. -- --
--   maxLengthOf n = failureUnless ((<=n) . length)
--   
maxLengthOf :: Foldable t => Int -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a maximum value (inclusive) rule. -- --
--   maxValueOf x = failureUnless (<=x)
--   
maxValueOf :: Ord a => a -> e -> ValidationRule (NonEmpty e) a -- | Build a minimum length (inclusive) rule. -- --
--   minLengthOf x = failureUnless ((>=n) . length)
--   
minLengthOf :: Foldable t => Int -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a minimum value (inclusive) rule. -- --
--   minValueOf x = failureUnless (>=x)
--   
minValueOf :: Ord a => a -> e -> ValidationRule (NonEmpty e) a -- | Build an equality rule for value. -- --
--   mustBe x = failureUnless (==x)
--   
mustBe :: Eq a => a -> e -> ValidationRule (NonEmpty e) a -- | Build an elem rule. -- --
--   mustContain x = atleastContains (==x)
--   
-- --
--   mustContain x = failureUnless (elem x)
--   
mustContain :: (Foldable t, Eq a) => a -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a maximum length rule. -- --
--   notEmpty = minLengthOf 1
--   
-- --
--   notEmpty = failureIf null
--   
notEmpty :: Foldable t => e -> ValidationRule (NonEmpty e) (t a) -- | Build an equality rule for length. -- --
--   ofLength x = failureUnless ((==x) . length)
--   
ofLength :: Foldable t => Int -> e -> ValidationRule (NonEmpty e) (t a) -- | Build an all rule. -- --
--   onlyContains x = failureUnless (all x)
--   
onlyContains :: Foldable t => (a -> Bool) -> e -> ValidationRule (NonEmpty e) (t a) -- | Build a minimum value (exclusive) rule. -- --
--   valueAbove x = minValueOf (x + 1)
--   
-- --
--   valueAbove x = failureUnless (>x)
--   
valueAbove :: Ord a => a -> e -> ValidationRule (NonEmpty e) a -- | Build a maximum value (exclusive) rule. -- --
--   valueBelow x = minValueOf (x - 1)
--   
-- --
--   valueBelow x = failureUnless (<x)
--   
valueBelow :: Ord a => a -> e -> ValidationRule (NonEmpty e) a -- | Build an inRange rule for value. -- --
--   valueWithin (m, n) = minValueOf m `andAlso` maxValueOf n
--   
-- --
--   valueWithin (m, n) = failureUnless (x -> m <= x && x <= n)
--   
valueWithin :: Ord a => (a, a) -> e -> ValidationRule (NonEmpty e) a -- | Like atleastContains but uses Unit as the -- ValidationRule error type. atleastContains' :: Foldable t => (a -> Bool) -> ValidationRule () (t a) -- | Like lengthAbove but uses Unit as the -- ValidationRule error type. lengthAbove' :: Foldable t => Int -> ValidationRule () (t a) -- | Like lengthBelow but uses Unit as the -- ValidationRule error type. lengthBelow' :: Foldable t => Int -> ValidationRule () (t a) -- | Like lengthWithin but uses Unit as the -- ValidationRule error type. lengthWithin' :: Foldable t => (Int, Int) -> ValidationRule () (t a) -- | Like maxLengthOf but uses Unit as the -- ValidationRule error type. maxLengthOf' :: Foldable t => Int -> ValidationRule () (t a) -- | Like maxValueOf but uses Unit as the -- ValidationRule error type. maxValueOf' :: Ord a => a -> ValidationRule () a -- | Like minLengthOf but uses Unit as the -- ValidationRule error type. minLengthOf' :: Foldable t => Int -> ValidationRule () (t a) -- | Like minValueOf but uses Unit as the -- ValidationRule error type. minValueOf' :: Ord a => a -> ValidationRule () a -- | Like mustBe but uses Unit as the ValidationRule -- error type. mustBe' :: Eq a => a -> ValidationRule () a -- | Like mustContain but uses Unit as the -- ValidationRule error type. mustContain' :: (Foldable t, Eq a) => a -> ValidationRule () (t a) -- | Like notEmpty but uses Unit as the ValidationRule -- error type. notEmpty' :: Foldable t => ValidationRule () (t a) -- | Like ofLength but uses Unit as the ValidationRule -- error type. ofLength' :: Foldable t => Int -> ValidationRule () (t a) -- | Like onlyContains but uses Unit as the -- ValidationRule error type. onlyContains' :: Foldable t => (a -> Bool) -> ValidationRule () (t a) -- | Like valueAbove but uses Unit as the -- ValidationRule error type. valueAbove' :: Ord a => a -> ValidationRule () a -- | Like valueBelow but uses Unit as the -- ValidationRule error type. valueBelow' :: Ord a => a -> ValidationRule () a -- | Like valueWithin but uses Unit as the -- ValidationRule error type. valueWithin' :: Ord a => (a, a) -> ValidationRule () a -- | Build a rule that runs given rule only if input is Just. -- -- Yields Success when input is Nothing. -- --

Examples

-- --
--   >>> runValidator (validate (optionally (failureIf even "Even"))) (Just 5)
--   Success (Just 5)
--   
--   >>> runValidator (validate (optionally (failureIf even "Even"))) (Just 6)
--   Failure ("Even" :| [])
--   
--   >>> runValidator (validate (optionally (failureIf even "Even"))) Nothing
--   Success Nothing
--   
optionally :: ValidationRule e a -> ValidationRule e (Maybe a) -- | This module exports the primary validator building functions. It also -- exports all of Valida.Combinators. -- -- Refer to the hackage documentation for function reference and -- examples. You can also find examples in the README, and also in the -- github repo, within the examples directory. module Valida -- | Convenience alias for functions that "select" a record field. type Selector a b = a -> b -- | Like Either, but accumulates failures upon applicative -- composition. data Validation e a -- | Represents a validation failure with an error. Failure :: e -> Validation e a -- | Represents a successful validation with the validated value. Success :: a -> Validation e a -- | The rule a Validator uses to run validation. -- -- Contains a function that accepts the target type and returns a -- Validation result. -- -- The type- ValidationRule (NonEmpty String) Int, designates a -- rule that verifies the validity of an Int, and uses a value of -- type NonEmpty String to represent error, in case of failure. data ValidationRule e a -- | An applicative validator. Validates a predicate on an input when run -- and returns the Validation result. data Validator e inp a -- | Build a basic validator from a ValidationRule. -- -- The Validator runs the rule on its input. If validation is -- successful, the input is put into the Validation result. -- --
--   validate rule = verify rule id
--   
validate :: ValidationRule e a -> Validator e a a -- | Build a validator from a ValidationRule and a Selector. -- -- The Validator first runs given selector on its input to -- obtain the validation target. Then, it runs the ValidationRule -- on the target. -- -- If validation is successful, the validation target is put into the -- Validation result. -- --

Examples

-- -- This is the primary function for building validators for your record -- types. To validate a pair, the most basic record type, such that the -- first element is a non empty string, and the second element is a -- number greater than 9, you can use: -- --
--   >>> let pairValidator = (,) <$> verify (notEmpty "EmptyString") fst <*> verify (failureIf (<10) "LessThan10") snd
--   
-- -- You can then run the validator on your input, using -- runValidator: >>> runValidator pairValidator ("foo", -- 12) Success ("foo",12) >>> runValidator pairValidator ("", -- 12) Failure (EmptyString :| []) >>> runValidator -- pairValidator ("foo", 9) Failure (LessThan10 :| []) -- >>> runValidator pairValidator ("", 9) Failure -- (EmptyString :| [LessThan10]) verify :: ValidationRule e b -> Selector a b -> Validator e a b -- | Low level function to manually build a ValidationRule. You -- should use the combinators instead. -- --

Examples

-- --
--   >>> runValidator (validate (vrule (\x -> if isDigit x then Success () else Failure "NotDigit"))) 'a'
--   Failure "NotDigit"
--   
--   >>> runValidator (validate (vrule (\x -> if isDigit x then Success () else Failure "NotDigit"))) '5'
--   Success '5'
--   
vrule :: (a -> Validation e ()) -> ValidationRule e a -- | A synonym for verify with its arguments flipped. (-?>) :: Selector a b -> ValidationRule e b -> Validator e a b infix 5 -?> -- | Relabel a ValidationRule with a different error. -- -- Many combinators, like failureIf' and failureUnless', -- simply return the given error value within NonEmpty upon -- failure. You can use label to override this return value. -- --

Examples

-- --
--   >>> let rule = label "NotEven" (failureUnless' even)
--   
--   >>> runValidator (validate rule) 1
--   Failure "NotEven"
--   
-- --
--   >>> let rule = label "DefinitelyNotEven" (failureUnless even "NotEven")
--   
--   >>> runValidator (validate rule) 1
--   Failure "DefinitelyNotEven"
--   
label :: e -> ValidationRule x a -> ValidationRule e a -- | Relabel a Validator with a different error. -- --

Examples

-- --
--   >>> let validator = labelV "NotEven" (validate (failureUnless' even))
--   
--   >>> runValidator validator 1
--   Failure "NotEven"
--   
-- --
--   >>> let validator = labelV "DefinitelyNotEven" (validate (failureUnless even "NotEven"))
--   
--   >>> runValidator validator 1
--   Failure "DefinitelyNotEven"
--   
labelV :: e -> Validator x inp a -> Validator e inp a -- | A synonym for label with its arguments flipped. () :: ValidationRule x a -> e -> ValidationRule e a infix 6 -- | A synonym for labelV with its arguments flipped. () :: Validator x inp a -> e -> Validator e inp a infix 6 -- | Convert a Either to an Validation. -- -- Given, Either e a- -- -- -- --

Examples

-- --
--   >>> fromEither (Right 'c' :: Either String Char)
--   Success 'c'
--   
--   >>> fromEither (Left 42 :: Either Int Char)
--   Failure 42
--   
fromEither :: Either e a -> Validation e a -- | Convert a Validation to an Either. -- -- Given, Validation a b- -- -- -- --

Examples

-- --
--   >>> toEither (Success 'c' :: Validation String Char)
--   Right 'c'
--   
--   >>> toEither (Failure 42 :: Validation Int Char)
--   Left 42
--   
toEither :: Validation a b -> Either a b -- | Case analysis for Validation, i.e catamorphism. -- -- In case of 'Failure e', apply the first function to e; in case of -- 'Success a', apply the second function to a. -- -- This is a more generalized version of the bifoldMap -- implementation. -- --

Examples

-- --
--   >>> validation (const Nothing) Just (Success 'c' :: Validation String Char)
--   Just 'c'
--   
--   >>> validation (const Nothing) Just (Failure "error" :: Validation String Char)
--   Nothing
--   
validation :: (e -> c) -> (a -> c) -> Validation e a -> c -- | Case analysis for Validation, with replacer. -- -- This is similar to validation, but takes in replacers instead -- of functions. -- -- In case of Failure, return the first argument; otherwise, -- return the second argument. -- --
--   validationConst e a = validation (const e) (const a)
--   
-- --

Examples

-- --
--   >>> validation (const Nothing) Just (Success 'c' :: Validation String Char)
--   Just 'c'
--   
--   >>> validation (const Nothing) Just (Failure "error" :: Validation String Char)
--   Nothing
--   
validationConst :: p -> p -> Validation e a -> p -- | Return the contents of a Success-value or a default value -- otherwise. -- --

Examples

-- --
--   >>> fromSuccess 0 (Success 48 :: Validation Int Int)
--   48
--   
--   >>> fromSuccess 0 (Failure 27 :: Validation Int Int)
--   0
--   
fromSuccess :: a -> Validation e a -> a -- | Return the contents of a Failure-value or a default value -- otherwise. -- --

Examples

-- --
--   >>> fromFailure 0 (Success 48 :: Validation Int Int)
--   0
--   
--   >>> fromFailure 0 (Failure 27 :: Validation Int Int)
--   27
--   
fromFailure :: e -> Validation e a -> e -- | Return True if the given value is a Success-value, False -- otherwise. isSuccess :: Validation e a -> Bool -- | Return True if the given value is a Failure-value, False -- otherwise. isFailure :: Validation e a -> Bool -- | Extracts from a list of Validation all the Success elements, in -- order. -- --

Examples

-- --
--   >>> successes [Success 1, Failure "err1", Failure "err2", Success 2, Failure "err3"]
--   [1,2]
--   
--   >>> successes ([Failure "err1", Failure "err2", Failure "err3"] :: [Validation String Int])
--   []
--   
successes :: [Validation e a] -> [a] -- | Extracts from a list of Validation all the Failure -- values, in order. -- --

Examples

-- --
--   >>> failures [Success 48, Failure "err1", Failure "err2", Success 2, Failure "err3"]
--   ["err1","err2","err3"]
--   
--   >>> failures ([Success 1, Success 2, Success 3] :: [Validation String Int])
--   []
--   
failures :: [Validation e a] -> [e] -- | Partitions a list of Either into two lists. -- -- All the Left elements are extracted, in order, to the first component -- of the output. Similarly the Right elements are extracted to the -- second component of the output. -- --
--   partitionValidations xs = (failures xs, successes xs)
--   
-- --

Examples

-- --
--   >>> partitionValidations [Success 1, Failure "err1", Failure "err2", Success 2, Failure "err3"]
--   (["err1","err2","err3"],[1,2])
--   
partitionValidations :: [Validation e a] -> ([e], [a])