Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
In type theory, a refinement type is a type endowed with a predicate which is assumed to hold for any element of the refined type.
This library allows one to capture the idea of a refinement type
using the Refined
type. A Refined
p
x
wraps a value
of type x
, ensuring that it satisfies a type-level predicate p
.
A simple introduction to this library can be found here: http://nikita-volkov.github.io/refined/
Synopsis
- data Refined (p :: k) x
- refine :: forall p x. Predicate p x => x -> Either RefineException (Refined p x)
- refine_ :: forall p x. Predicate p x => x -> Either RefineException x
- refineThrow :: (Predicate p x, MonadThrow m) => x -> m (Refined p x)
- refineFail :: (Predicate p x, MonadFail m) => x -> m (Refined p x)
- refineError :: (Predicate p x, MonadError RefineException m) => x -> m (Refined p x)
- refineEither :: forall p x. Predicate p x => x -> Either (Refined (Not p) x) (Refined p x)
- refineTH :: forall p x m. (Predicate p x, Lift x, Quote m, MonadFail m) => x -> Code m (Refined p x)
- refineTH_ :: forall p x m. (Predicate p x, Lift x, Quote m, MonadFail m) => x -> Code m x
- unrefine :: Refined p x -> x
- data Refined1 (p :: k) f x
- refine1 :: forall p f x. Predicate1 p f => f x -> Either RefineException (Refined1 p f x)
- unrefine1 :: Refined1 p f x -> f x
- class (Typeable p, Typeable k) => Predicate (p :: k) x where
- validate :: Proxy p -> x -> Maybe RefineException
- validate' :: forall {k} p x. Predicate (p :: k) x => Proxy p -> x -> Maybe RefineException
- reifyPredicate :: forall p a. Predicate p a => a -> Bool
- class (Typeable p, Typeable k) => Predicate1 (p :: k) f where
- validate1 :: Proxy p -> f a -> Maybe RefineException
- validate1' :: forall {k} p f a. Predicate1 (p :: k) f => Proxy p -> f a -> Maybe RefineException
- data Not p = Not
- data And l r = And
- type (&&) = And
- data Or l r = Or
- type (||) = Or
- data Xor l r = Xor
- data IdPred = IdPred
- data LessThan (n :: Nat) = LessThan
- data GreaterThan (n :: Nat) = GreaterThan
- data From (n :: Nat) = From
- data To (n :: Nat) = To
- data FromTo (mn :: Nat) (mx :: Nat) = FromTo
- data NegativeFromTo (n :: Nat) (m :: Nat) = NegativeFromTo
- data EqualTo (n :: Nat) = EqualTo
- data NotEqualTo (n :: Nat) = NotEqualTo
- data Odd = Odd
- data Even = Even
- data DivisibleBy (n :: Nat) = DivisibleBy
- data NaN = NaN
- data Infinite = Infinite
- type Positive = GreaterThan 0
- type NonPositive = To 0
- type Negative = LessThan 0
- type NonNegative = From 0
- type ZeroToOne = FromTo 0 1
- type NonZero = NotEqualTo 0
- data SizeLessThan (n :: Nat) = SizeLessThan
- data SizeGreaterThan (n :: Nat) = SizeGreaterThan
- data SizeEqualTo (n :: Nat) = SizeEqualTo
- type Empty = SizeEqualTo 0
- type NonEmpty = SizeGreaterThan 0
- data Ascending = Ascending
- data Descending = Descending
- class Weaken from to where
- andLeft :: Refined (And l r) x -> Refined l x
- andRight :: Refined (And l r) x -> Refined r x
- leftOr :: Refined l x -> Refined (Or l r) x
- rightOr :: Refined r x -> Refined (Or l r) x
- weakenAndLeft :: Weaken from to => Refined (And from x) a -> Refined (And to x) a
- weakenAndRight :: Weaken from to => Refined (And x from) a -> Refined (And x to) a
- weakenOrLeft :: Weaken from to => Refined (And from x) a -> Refined (And to x) a
- weakenOrRight :: Weaken from to => Refined (And x from) a -> Refined (And x to) a
- strengthen :: forall p p' x. (Predicate p x, Predicate p' x) => Refined p x -> Either RefineException (Refined (p && p') x)
- data RefineException
- = RefineNotException !TypeRep
- | RefineAndException !TypeRep !(These RefineException RefineException)
- | RefineOrException !TypeRep !RefineException !RefineException
- | RefineXorException !TypeRep !(Maybe (RefineException, RefineException))
- | RefineSomeException !TypeRep !SomeException
- | RefineOtherException !TypeRep !Text
- displayRefineException :: RefineException -> String
- throwRefineOtherException :: TypeRep -> Text -> Maybe RefineException
- throwRefineSomeException :: TypeRep -> SomeException -> Maybe RefineException
- success :: Maybe RefineException
Refined
type
data Refined (p :: k) x Source #
A refinement type, which wraps a value of type x
.
Since: 0.1.0.0
Instances
Creation
refine :: forall p x. Predicate p x => x -> Either RefineException (Refined p x) Source #
A smart constructor of a Refined
value.
Checks the input value at runtime.
Since: 0.1.0.0
refine_ :: forall p x. Predicate p x => x -> Either RefineException x Source #
Like refine
, but discards the refinement.
This _can_ be useful when you only need to validate
that some value at runtime satisfies some predicate.
See also reifyPredicate
.
Since: 0.4.4
refineThrow :: (Predicate p x, MonadThrow m) => x -> m (Refined p x) Source #
refineError :: (Predicate p x, MonadError RefineException m) => x -> m (Refined p x) Source #
Constructs a Refined
value at run-time,
calling throwError
if the value
does not satisfy the predicate.
Since: 0.2.0.0
refineEither :: forall p x. Predicate p x => x -> Either (Refined (Not p) x) (Refined p x) Source #
Like refine
, but, when the value doesn't satisfy the predicate, returns
a Refined
value with the predicate negated, instead of returning
RefineException
.
>>>
isRight (refineEither @Even @Int 42)
True
>>>
isLeft (refineEither @Even @Int 43)
True
refineTH :: forall p x m. (Predicate p x, Lift x, Quote m, MonadFail m) => x -> Code m (Refined p x) Source #
Constructs a Refined
value at compile-time using -XTemplateHaskell
.
For example:
$$(refineTH 23) :: Refined Positive Int Refined 23
Here's an example of an invalid value:
$$(refineTH 0) :: Refined Positive Int <interactive>:6:4: Value is not greater than 0 In the Template Haskell splice $$(refineTH 0) In the expression: $$(refineTH 0) :: Refined Positive Int In an equation for ‘it’: it = $$(refineTH 0) :: Refined Positive Int
The example above indicates a compile-time failure, which means that the checking was done at compile-time, thus introducing a zero-runtime overhead compared to a plain value construction.
Note: It may be useful to use this function with the th-lift-instances package.
Since: 0.1.0.0
refineTH_ :: forall p x m. (Predicate p x, Lift x, Quote m, MonadFail m) => x -> Code m x Source #
Like refineTH
, but immediately unrefines the value.
This is useful when some value need only be refined
at compile-time.
Since: 0.4.4
Consumption
Refined1
type
data Refined1 (p :: k) f x Source #
A refinement type, which wraps a value of type f x
.
The predicate is applied over the functor f
. Thus, we may safely recover
various Functor
y instances, because no matter what you do to the
values inside the functor, the predicate may not be invalidated.
Instances
Creation
refine1 :: forall p f x. Predicate1 p f => f x -> Either RefineException (Refined1 p f x) Source #
A smart constructor of a Refined1
value.
Checks the input value at runtime.
Since: 0.1.0.0
Consumption
Predicate
class (Typeable p, Typeable k) => Predicate (p :: k) x where Source #
A typeclass which defines a runtime interpretation of
a type-level predicate p
for type x
.
Since: 0.1.0.0
validate :: Proxy p -> x -> Maybe RefineException Source #
Check the value x
according to the predicate p
,
producing an error RefineException
if the value
does not satisfy.
Note: validate
is not intended to be used
directly; instead, it is intended to provide the minimal
means necessary for other utilities to be derived. As
such, the Maybe
here should be interpreted to mean
the presence or absence of a RefineException
, and
nothing else.
Note that due to GHC's type variable order rules, this function has an
implicit kind in position 1, which makes TypeApplications awkward. Use
validate'
for nicer behaviour.
Instances
validate' :: forall {k} p x. Predicate (p :: k) x => Proxy p -> x -> Maybe RefineException Source #
Check the value x
according to the predicate p
,
producing an error RefineException
if the value
does not satisfy.
Same as validate
but with more convenient type variable order for a better
TypeApplications experience.
reifyPredicate :: forall p a. Predicate p a => a -> Bool Source #
Reify a Predicate
by turning it into a value-level predicate.
Since: 0.4.2.3
Predicate1
class (Typeable p, Typeable k) => Predicate1 (p :: k) f where Source #
A typeclass which defines a runtime interpretation of
a type-level predicate p
for type forall a. f a
.
The inner type may not be inspected. If you find yourself needing to add
constraints to it, you want Predicate
.
validate1 :: Proxy p -> f a -> Maybe RefineException Source #
Check the value f a
according to the predicate p
,
producing an error RefineException
if the value
does not satisfy.
Note: validate1
is not intended to be used
directly; instead, it is intended to provide the minimal
means necessary for other utilities to be derived. As
such, the Maybe
here should be interpreted to mean
the presence or absence of a RefineException
, and
nothing else.
Note that due to GHC's type variable order rules, this function has an
implicit kind in position 1, which makes TypeApplications awkward. Use
validate1'
for nicer behaviour.
Instances
(Foldable t, KnownNat n) => Predicate1 (SizeEqualTo n :: Type) (t :: TYPE LiftedRep -> Type) Source # | |
Defined in Refined validate1 :: forall (a :: k). Proxy (SizeEqualTo n) -> t a -> Maybe RefineException Source # | |
(Foldable t, KnownNat n) => Predicate1 (SizeGreaterThan n :: Type) (t :: TYPE LiftedRep -> Type) Source # | |
Defined in Refined validate1 :: forall (a :: k). Proxy (SizeGreaterThan n) -> t a -> Maybe RefineException Source # | |
(Foldable t, KnownNat n) => Predicate1 (SizeLessThan n :: Type) (t :: TYPE LiftedRep -> Type) Source # | |
Defined in Refined validate1 :: forall (a :: k). Proxy (SizeLessThan n) -> t a -> Maybe RefineException Source # |
validate1' :: forall {k} p f a. Predicate1 (p :: k) f => Proxy p -> f a -> Maybe RefineException Source #
Check the value f a
according to the predicate p
,
producing an error RefineException
if the value
does not satisfy.
Same as validate1
but with more convenient type variable order for a better
TypeApplications experience.
Logical predicates
The negation of a predicate.
>>>
isRight (refine @(Not NonEmpty) @[Int] [])
True
>>>
isLeft (refine @(Not NonEmpty) @[Int] [1,2])
True
Since: 0.1.0.0
Not | Since: 0.4.2 |
The conjunction of two predicates.
>>>
isLeft (refine @(And Positive Negative) @Int 3)
True
>>>
isRight (refine @(And Positive Odd) @Int 203)
True
Since: 0.1.0.0
And | Since: 0.4.2 |
The disjunction of two predicates.
>>>
isRight (refine @(Or Even Odd) @Int 3)
True
>>>
isRight (refine @(Or (LessThan 3) (GreaterThan 3)) @Int 2)
True
>>>
isRight (refine @(Or Even Even) @Int 4)
True
Since: 0.1.0.0
Or | Since: 0.4.2 |
The exclusive disjunction of two predicates.
>>>
isRight (refine @(Xor Even Odd) @Int 3)
True
>>>
isLeft (refine @(Xor (LessThan 3) (EqualTo 2)) @Int 2)
True
>>>
isLeft (refine @(Xor Even Even) @Int 2)
True
Since: 0.5
Xor | Since: 0.5 |
Identity predicate
A predicate which is satisfied for all types.
Arguments passed to
in validate
are not evaluated.validate
IdPred
x
>>>
isRight (refine @IdPred @Int undefined)
True
>>>
isLeft (refine @IdPred @Int undefined)
False
Since: 0.3.0.0
IdPred | Since: 0.4.2 |
Numeric predicates
data LessThan (n :: Nat) Source #
A Predicate
ensuring that the value is less than the
specified type-level number.
>>>
isRight (refine @(LessThan 12) @Int 11)
True
>>>
isLeft (refine @(LessThan 12) @Int 12)
True
Since: 0.1.0.0
LessThan | Since: 0.4.2 |
Instances
n <= m => Weaken (LessThan n :: Type) (LessThan m :: Type) Source # | Since: 0.2.0.0 |
n <= m => Weaken (LessThan n :: Type) (To m :: Type) Source # | Since: 0.2.0.0 |
(Ord x, Num x, KnownNat n) => Predicate (LessThan n :: Type) x Source # | Since: 0.1.0.0 |
Generic (LessThan n) Source # | |
type Rep (LessThan n) Source # | Since: 0.3.0.0 |
data GreaterThan (n :: Nat) Source #
A Predicate
ensuring that the value is greater than the
specified type-level number.
>>>
isRight (refine @(GreaterThan 65) @Int 67)
True
>>>
isLeft (refine @(GreaterThan 65) @Int 65)
True
Since: 0.1.0.0
GreaterThan | Since: 0.4.2 |
Instances
m <= n => Weaken (GreaterThan n :: Type) (From m :: Type) Source # | Since: 0.2.0.0 |
m <= n => Weaken (GreaterThan n :: Type) (GreaterThan m :: Type) Source # | Since: 0.2.0.0 |
Defined in Refined weaken :: Refined (GreaterThan n) x -> Refined (GreaterThan m) x Source # | |
(Ord x, Num x, KnownNat n) => Predicate (GreaterThan n :: Type) x Source # | Since: 0.1.0.0 |
Defined in Refined validate :: Proxy (GreaterThan n) -> x -> Maybe RefineException Source # | |
Generic (GreaterThan n) Source # | |
Defined in Refined from :: GreaterThan n -> Rep (GreaterThan n) x Source # to :: Rep (GreaterThan n) x -> GreaterThan n Source # | |
type Rep (GreaterThan n) Source # | Since: 0.3.0.0 |
A Predicate
ensuring that the value is greater than or equal to the
specified type-level number.
>>>
isRight (refine @(From 9) @Int 10)
True
>>>
isRight (refine @(From 10) @Int 10)
True
>>>
isLeft (refine @(From 11) @Int 10)
True
Since: 0.1.2
From | Since: 0.4.2 |
Instances
m <= n => Weaken (From n :: Type) (From m :: Type) Source # | Since: 0.2.0.0 |
m <= n => Weaken (GreaterThan n :: Type) (From m :: Type) Source # | Since: 0.2.0.0 |
p <= n => Weaken (FromTo n m :: Type) (From p :: Type) Source # | Since: 0.2.0.0 |
(Ord x, Num x, KnownNat n) => Predicate (From n :: Type) x Source # | Since: 0.1.2 |
Generic (From n) Source # | |
type Rep (From n) Source # | Since: 0.3.0.0 |
A Predicate
ensuring that the value is less than or equal to the
specified type-level number.
>>>
isRight (refine @(To 23) @Int 17)
True
>>>
isLeft (refine @(To 17) @Int 23)
True
Since: 0.1.2
To | Since: 0.4.2 |
Instances
n <= m => Weaken (LessThan n :: Type) (To m :: Type) Source # | Since: 0.2.0.0 |
n <= m => Weaken (To n :: Type) (To m :: Type) Source # | Since: 0.2.0.0 |
m <= q => Weaken (FromTo n m :: Type) (To q :: Type) Source # | Since: 0.2.0.0 |
(Ord x, Num x, KnownNat n) => Predicate (To n :: Type) x Source # | Since: 0.1.2 |
Generic (To n) Source # | |
type Rep (To n) Source # | Since: 0.3.0.0 |
data FromTo (mn :: Nat) (mx :: Nat) Source #
A Predicate
ensuring that the value is within an inclusive range.
>>>
isRight (refine @(FromTo 0 16) @Int 13)
True
>>>
isRight (refine @(FromTo 13 15) @Int 13)
True
>>>
isRight (refine @(FromTo 13 15) @Int 15)
True
>>>
isLeft (refine @(FromTo 13 15) @Int 12)
True
Since: 0.1.2
FromTo | Since: 0.4.2 |
Instances
p <= n => Weaken (FromTo n m :: Type) (From p :: Type) Source # | Since: 0.2.0.0 |
m <= q => Weaken (FromTo n m :: Type) (To q :: Type) Source # | Since: 0.2.0.0 |
(p <= n, m <= q) => Weaken (FromTo n m :: Type) (FromTo p q :: Type) Source # | Since: 0.2.0.0 |
(Ord x, Num x, KnownNat mn, KnownNat mx, mn <= mx) => Predicate (FromTo mn mx :: Type) x Source # | Since: 0.1.2 |
Generic (FromTo mn mx) Source # | |
type Rep (FromTo mn mx) Source # | Since: 0.3.0.0 |
data NegativeFromTo (n :: Nat) (m :: Nat) Source #
A Predicate
ensuring that the value is greater or equal than a negative
number specified as a type-level (positive) number n
and less than a
type-level (positive) number m
.
>>>
isRight (refine @(NegativeFromTo 5 12) @Int (-3))
True
>>>
isLeft (refine @(NegativeFromTo 4 3) @Int (-5))
True
Since: 0.4
NegativeFromTo | Since: 0.4.2 |
Instances
(Ord x, Num x, KnownNat n, KnownNat m) => Predicate (NegativeFromTo n m :: Type) x Source # | Since: 0.4 |
Defined in Refined validate :: Proxy (NegativeFromTo n m) -> x -> Maybe RefineException Source # | |
Generic (NegativeFromTo n m) Source # | |
Defined in Refined from :: NegativeFromTo n m -> Rep (NegativeFromTo n m) x Source # to :: Rep (NegativeFromTo n m) x -> NegativeFromTo n m Source # | |
type Rep (NegativeFromTo n m) Source # | Since: 0.3.0.0 |
data EqualTo (n :: Nat) Source #
A Predicate
ensuring that the value is equal to the specified
type-level number n
.
>>>
isRight (refine @(EqualTo 5) @Int 5)
True
>>>
isLeft (refine @(EqualTo 6) @Int 5)
True
Since: 0.1.0.0
EqualTo | Since: 0.4.2 |
data NotEqualTo (n :: Nat) Source #
A Predicate
ensuring that the value is not equal to the specified
type-level number n
.
>>>
isRight (refine @(NotEqualTo 6) @Int 5)
True
>>>
isLeft (refine @(NotEqualTo 5) @Int 5)
True
Since: 0.2.0.0
NotEqualTo | Since: 0.4.2 |
Instances
(Eq x, Num x, KnownNat n) => Predicate (NotEqualTo n :: Type) x Source # | Since: 0.2.0.0 |
Defined in Refined validate :: Proxy (NotEqualTo n) -> x -> Maybe RefineException Source # | |
Generic (NotEqualTo n) Source # | |
Defined in Refined from :: NotEqualTo n -> Rep (NotEqualTo n) x Source # to :: Rep (NotEqualTo n) x -> NotEqualTo n Source # | |
type Rep (NotEqualTo n) Source # | Since: 0.3.0.0 |
A Predicate
ensuring that the value is odd.
>>>
isRight (refine @Odd @Int 33)
True
>>>
isLeft (refine @Odd @Int 32)
True
Since: 0.4.2
Odd | Since: 0.4.2 |
A Predicate
ensuring that the value is even.
>>>
isRight (refine @Even @Int 32)
True
>>>
isLeft (refine @Even @Int 33)
True
Since: 0.4.2
Even | Since: 0.4.2 |
data DivisibleBy (n :: Nat) Source #
A Predicate
ensuring that the value is divisible by n
.
>>>
isRight (refine @(DivisibleBy 3) @Int 12)
True
>>>
isLeft (refine @(DivisibleBy 2) @Int 37)
True
Since: 0.4.2
DivisibleBy | Since: 0.4.2 |
Instances
(Integral x, KnownNat n) => Predicate (DivisibleBy n :: Type) x Source # | Since: 0.4.2 |
Defined in Refined validate :: Proxy (DivisibleBy n) -> x -> Maybe RefineException Source # | |
Generic (DivisibleBy n) Source # | |
Defined in Refined from :: DivisibleBy n -> Rep (DivisibleBy n) x Source # to :: Rep (DivisibleBy n) x -> DivisibleBy n Source # | |
type Rep (DivisibleBy n) Source # | Since: 0.3.0.0 |
A Predicate
ensuring that the value is IEEE "not-a-number" (NaN).
>>>
isRight (refine @NaN @Double (0/0))
True
>>>
isLeft (refine @NaN @Double 13.9)
True
Since: 0.5
NaN | Since: 0.5 |
A Predicate
ensuring that the value is IEEE infinity or negative infinity.
>>>
isRight (refine @Infinite @Double (1/0))
True
>>>
isRight (refine @Infinite @Double (-1/0))
True
>>>
isLeft (refine @Infinite @Double 13.20)
True
Since: 0.5
Infinite | Since: 0.5 |
type Positive = GreaterThan 0 Source #
A Predicate
ensuring that the value is greater than zero.
Since: 0.1.0.0
type NonPositive = To 0 Source #
A Predicate
ensuring that the value is less than or equal to zero.
Since: 0.1.2
type Negative = LessThan 0 Source #
A Predicate
ensuring that the value is less than zero.
Since: 0.1.0.0
type NonNegative = From 0 Source #
A Predicate
ensuring that the value is greater than or equal to zero.
Since: 0.1.2
type NonZero = NotEqualTo 0 Source #
A Predicate
ensuring that the value is not equal to zero.
Since: 0.2.0.0
Foldable predicates
Size predicates
data SizeLessThan (n :: Nat) Source #
A Predicate
ensuring that the value has a length
which is less than the specified type-level number.
>>>
isRight (refine @(SizeLessThan 4) @[Int] [1,2,3])
True
>>>
isLeft (refine @(SizeLessThan 5) @[Int] [1,2,3,4,5])
True
>>>
isRight (refine @(SizeLessThan 4) @Text "Hi")
True
>>>
isLeft (refine @(SizeLessThan 4) @Text "Hello")
True
Since: 0.2.0.0
SizeLessThan | Since: 0.4.2 |
Instances
data SizeGreaterThan (n :: Nat) Source #
A Predicate
ensuring that the value has a length
which is greater than the specified type-level number.
>>>
isLeft (refine @(SizeGreaterThan 3) @[Int] [1,2,3])
True
>>>
isRight (refine @(SizeGreaterThan 3) @[Int] [1,2,3,4,5])
True
>>>
isLeft (refine @(SizeGreaterThan 4) @Text "Hi")
True
>>>
isRight (refine @(SizeGreaterThan 4) @Text "Hello")
True
Since: 0.2.0.0
SizeGreaterThan | Since: 0.4.2 |
Instances
data SizeEqualTo (n :: Nat) Source #
A Predicate
ensuring that the value has a length
which is equal to the specified type-level number.
>>>
isRight (refine @(SizeEqualTo 4) @[Int] [1,2,3,4])
True
>>>
isLeft (refine @(SizeEqualTo 35) @[Int] [1,2,3,4])
True
>>>
isRight (refine @(SizeEqualTo 4) @Text "four")
True
>>>
isLeft (refine @(SizeEqualTo 35) @Text "four")
True
Since: 0.2.0.0
SizeEqualTo | Since: 0.4.2 |
Instances
type Empty = SizeEqualTo 0 Source #
A Predicate
ensuring that the type is empty.
Since: 0.5
type NonEmpty = SizeGreaterThan 0 Source #
A Predicate
ensuring that the type is non-empty.
Since: 0.2.0.0
Ordering predicates
A Predicate
ensuring that the Foldable
contains elements
in a strictly ascending order.
>>>
isRight (refine @Ascending @[Int] [5, 8, 13, 21, 34])
True
>>>
isLeft (refine @Ascending @[Int] [34, 21, 13, 8, 5])
True
Since: 0.2.0.0
Ascending | Since: 0.4.2 |
data Descending Source #
A Predicate
ensuring that the Foldable
contains elements
in a strictly descending order.
>>>
isRight (refine @Descending @[Int] [34, 21, 13, 8, 5])
True
>>>
isLeft (refine @Descending @[Int] [5, 8, 13, 21, 34])
True
Since: 0.2.0.0
Descending | Since: 0.4.2 |
Instances
Generic Descending Source # | |
Defined in Refined from :: Descending -> Rep Descending x Source # to :: Rep Descending x -> Descending Source # | |
(Foldable t, Ord a) => Predicate Descending (t a) Source # | Since: 0.2.0.0 |
Defined in Refined validate :: Proxy Descending -> t a -> Maybe RefineException Source # | |
type Rep Descending Source # | Since: 0.3.0.0 |
Weakening
class Weaken from to where Source #
A typeclass containing "safe" conversions between refined predicates where the target is weaker than the source: that is, all values that satisfy the first predicate will be guaranteed to satisfy the second.
Take care: writing an instance declaration for your custom
predicates is the same as an assertion that weaken
is
safe to use:
instance Weaken
Pred1 Pred2
For most of the instances, explicit type annotations for the result value's type might be required.
Since: 0.2.0.0
Nothing
Instances
m <= n => Weaken (From n :: Type) (From m :: Type) Source # | Since: 0.2.0.0 |
m <= n => Weaken (GreaterThan n :: Type) (From m :: Type) Source # | Since: 0.2.0.0 |
m <= n => Weaken (GreaterThan n :: Type) (GreaterThan m :: Type) Source # | Since: 0.2.0.0 |
Defined in Refined weaken :: Refined (GreaterThan n) x -> Refined (GreaterThan m) x Source # | |
n <= m => Weaken (LessThan n :: Type) (LessThan m :: Type) Source # | Since: 0.2.0.0 |
n <= m => Weaken (LessThan n :: Type) (To m :: Type) Source # | Since: 0.2.0.0 |
m <= n => Weaken (SizeGreaterThan n :: Type) (SizeGreaterThan m :: Type) Source # | Since: 0.8.1 |
Defined in Refined weaken :: Refined (SizeGreaterThan n) x -> Refined (SizeGreaterThan m) x Source # | |
n <= m => Weaken (SizeLessThan n :: Type) (SizeLessThan m :: Type) Source # | Since: 0.8.1 |
Defined in Refined weaken :: Refined (SizeLessThan n) x -> Refined (SizeLessThan m) x Source # | |
n <= m => Weaken (To n :: Type) (To m :: Type) Source # | Since: 0.2.0.0 |
p <= n => Weaken (FromTo n m :: Type) (From p :: Type) Source # | Since: 0.2.0.0 |
m <= q => Weaken (FromTo n m :: Type) (To q :: Type) Source # | Since: 0.2.0.0 |
(p <= n, m <= q) => Weaken (FromTo n m :: Type) (FromTo p q :: Type) Source # | Since: 0.2.0.0 |
andLeft :: Refined (And l r) x -> Refined l x Source #
This function helps type inference. It is equivalent to the following:
instance Weaken (And l r) l
Since: 0.2.0.0
andRight :: Refined (And l r) x -> Refined r x Source #
This function helps type inference. It is equivalent to the following:
instance Weaken (And l r) r
Since: 0.2.0.0
leftOr :: Refined l x -> Refined (Or l r) x Source #
This function helps type inference. It is equivalent to the following:
instance Weaken l (Or l r)
Since: 0.2.0.0
rightOr :: Refined r x -> Refined (Or l r) x Source #
This function helps type inference. It is equivalent to the following:
instance Weaken r (Or l r)
Since: 0.2.0.0
weakenAndLeft :: Weaken from to => Refined (And from x) a -> Refined (And to x) a Source #
This function helps type inference. It is equivalent to the following:
instance Weaken from to => Weaken (And from x) (And to x)
Since: 0.8.1.0
weakenAndRight :: Weaken from to => Refined (And x from) a -> Refined (And x to) a Source #
This function helps type inference. It is equivalent to the following:
instance Weaken from to => Weaken (And x from) (And x to)
Since: 0.8.1.0
weakenOrLeft :: Weaken from to => Refined (And from x) a -> Refined (And to x) a Source #
This function helps type inference. It is equivalent to the following:
instance Weaken from to => Weaken (Or from x) (Or to x)
Since: 0.8.1.0
weakenOrRight :: Weaken from to => Refined (And x from) a -> Refined (And x to) a Source #
This function helps type inference. It is equivalent to the following:
instance Weaken from to => Weaken (Or x from) (Or x to)
Since: 0.8.1.0
Strengthening
strengthen :: forall p p' x. (Predicate p x, Predicate p' x) => Refined p x -> Either RefineException (Refined (p && p') x) Source #
Strengthen a refinement by composing it with another.
Since: 0.4.2.2
Error handling
RefineException
data RefineException Source #
An exception encoding the way in which a Predicate
failed.
Since: 0.2.0.0
RefineNotException !TypeRep | A Since: 0.2.0.0 |
RefineAndException !TypeRep !(These RefineException RefineException) | A Since: 0.2.0.0 |
RefineOrException !TypeRep !RefineException !RefineException | A Since: 0.2.0.0 |
RefineXorException !TypeRep !(Maybe (RefineException, RefineException)) | A Since: 0.5 |
RefineSomeException !TypeRep !SomeException | A Since: 0.5 |
RefineOtherException !TypeRep !Text | A Since: 0.2.0.0 |
Instances
displayRefineException :: RefineException -> String Source #
Display a RefineException
as String
This function can be extremely useful for debugging
, especially deeply nested ones.RefineException
s
Consider:
myRefinement = refine @(And (Not (LessThan 5)) (Xor (DivisibleBy 10) (And (EqualTo 4) (EqualTo 3) ) ) ) @Int 3
This function will show the following tree structure, recursively breaking down every issue:
And (Not (LessThan 5)) (Xor (EqualTo 4) (And (EqualTo 4) (EqualTo 3))) ├── The predicate (Not (LessThan 5)) does not hold. └── Xor (DivisibleBy 10) (And (EqualTo 4) (EqualTo 3)) ├── The predicate (DivisibleBy 10) failed with the message: Value is not divisible by 10 └── And (EqualTo 4) (EqualTo 3) └── The predicate (EqualTo 4) failed with the message: Value does not equal 4
Note: Equivalent to show
@RefineException
Since: 0.2.0.0
validate
helpers
throwRefineOtherException Source #
:: TypeRep | The |
-> Text | A |
-> Maybe RefineException |
A handler for a
.RefineException
throwRefineOtherException
is useful for defining what
behaviour validate
should have in the event of a predicate failure.
Typically the first argument passed to this function
will be the result of applying typeRep
to the first
argument of validate
.
Since: 0.2.0.0
throwRefineSomeException Source #
:: TypeRep | The |
-> SomeException | A custom exception. |
-> Maybe RefineException |
A handler for a
.RefineException
throwRefineSomeException
is useful for defining what
behaviour validate
should have in the event of a predicate failure
with a specific exception.
Since: 0.5
Orphan instances
(Arbitrary a, Typeable a, Typeable p, Predicate p a) => Arbitrary (Refined p a) Source # | Since: 0.4 |
(FromJSON a, Predicate p a) => FromJSON (Refined p a) Source # | Since: 0.4 |
(FromJSONKey a, Predicate p a) => FromJSONKey (Refined p a) Source # | |
fromJSONKey :: FromJSONKeyFunction (Refined p a) Source # fromJSONKeyList :: FromJSONKeyFunction [Refined p a] Source # | |
(ToJSON a, Predicate p a) => ToJSON (Refined p a) Source # | Since: 0.4 |
(ToJSONKey a, Predicate p a) => ToJSONKey (Refined p a) Source # | Since: 0.6.3 |
toJSONKey :: ToJSONKeyFunction (Refined p a) Source # toJSONKeyList :: ToJSONKeyFunction [Refined p a] Source # | |
(Read x, Predicate p x) => Read (Refined p x) Source # | This instance makes sure to check the refinement. Since: 0.1.0.0 |