refined-0.2.3.0: Refinement types with static and runtime checking

Safe HaskellNone
LanguageHaskell2010

Refined

Contents

Description

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

Refined

data Refined p x #

A refinement type, which wraps a value of type x, ensuring that it satisfies a type-level predicate p.

The only ways that this library provides to construct a value of type Refined are with the 'refine-' family of functions, because the use of the newtype constructor gets around the checking of the predicate. This restriction on the user makes unrefine safe.

If you would really like to construct a Refined value without checking the predicate, use unsafeCoerce.

Instances
Foldable (Refined p) # 
Instance details

Defined in Refined

Methods

fold :: Monoid m => Refined p m -> m #

foldMap :: Monoid m => (a -> m) -> Refined p a -> m #

foldr :: (a -> b -> b) -> b -> Refined p a -> b #

foldr' :: (a -> b -> b) -> b -> Refined p a -> b #

foldl :: (b -> a -> b) -> b -> Refined p a -> b #

foldl' :: (b -> a -> b) -> b -> Refined p a -> b #

foldr1 :: (a -> a -> a) -> Refined p a -> a #

foldl1 :: (a -> a -> a) -> Refined p a -> a #

toList :: Refined p a -> [a] #

null :: Refined p a -> Bool #

length :: Refined p a -> Int #

elem :: Eq a => a -> Refined p a -> Bool #

maximum :: Ord a => Refined p a -> a #

minimum :: Ord a => Refined p a -> a #

sum :: Num a => Refined p a -> a #

product :: Num a => Refined p a -> a #

Eq x => Eq (Refined p x) # 
Instance details

Defined in Refined

Methods

(==) :: Refined p x -> Refined p x -> Bool #

(/=) :: Refined p x -> Refined p x -> Bool #

Ord x => Ord (Refined p x) # 
Instance details

Defined in Refined

Methods

compare :: Refined p x -> Refined p x -> Ordering #

(<) :: Refined p x -> Refined p x -> Bool #

(<=) :: Refined p x -> Refined p x -> Bool #

(>) :: Refined p x -> Refined p x -> Bool #

(>=) :: Refined p x -> Refined p x -> Bool #

max :: Refined p x -> Refined p x -> Refined p x #

min :: Refined p x -> Refined p x -> Refined p x #

(Read x, Predicate p x) => Read (Refined p x) # 
Instance details

Defined in Refined

Show x => Show (Refined p x) # 
Instance details

Defined in Refined

Methods

showsPrec :: Int -> Refined p x -> ShowS #

show :: Refined p x -> String #

showList :: [Refined p x] -> ShowS #

Lift x => Lift (Refined p x) # 
Instance details

Defined in Refined

Methods

lift :: Refined p x -> Q Exp #

Creation

refine :: Predicate p x => x -> Either RefineException (Refined p x) #

A smart constructor of a Refined value. Checks the input value at runtime.

refineThrow :: (Predicate p x, MonadThrow m) => x -> m (Refined p x) #

Constructs a Refined value at run-time, calling throwM if the value does not satisfy the predicate.

refineFail :: (Predicate p x, MonadFail m) => x -> m (Refined p x) #

Constructs a Refined value at run-time, calling fail if the value does not satisfy the predicate.

refineError :: (Predicate p x, MonadError RefineException m) => x -> m (Refined p x) #

Constructs a Refined value at run-time, calling throwError if the value does not satisfy the predicate.

unsafeRefine :: Predicate p x => x -> Refined p x #

Constructs a Refined value at run-time, calling error if the value does not satisfy the predicate.

WARNING: this function is not total!

refineTH :: (Predicate p x, Lift x) => x -> Q (TExp (Refined p x)) #

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

If it's not evident, 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.

Consumption

unrefine :: Refined p x -> x #

Extracts the refined value.

Predicate

class Typeable p => Predicate p x where #

A typeclass which defines a runtime interpretation of a type-level predicate p for type x.

Minimal complete definition

validate

Methods

validate :: Monad m => p -> x -> RefineT m () #

Check the value x according to the predicate p, producing an error string if the value does not satisfy.

Instances
(IsList t, Ord (Item t)) => Predicate Descending t # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Descending -> t -> RefineT m () #

(IsList t, Ord (Item t)) => Predicate Ascending t # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Ascending -> t -> RefineT m () #

(Eq x, Num x, KnownNat n) => Predicate (NotEqualTo n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => NotEqualTo n -> x -> RefineT m () #

(Eq x, Num x, KnownNat n) => Predicate (EqualTo n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => EqualTo n -> x -> RefineT m () #

(Ord x, Num x, KnownNat n) => Predicate (To n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => To n -> x -> RefineT m () #

(Ord x, Num x, KnownNat n) => Predicate (From n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => From n -> x -> RefineT m () #

(Ord x, Num x, KnownNat n) => Predicate (GreaterThan n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => GreaterThan n -> x -> RefineT m () #

(Ord x, Num x, KnownNat n) => Predicate (LessThan n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => LessThan n -> x -> RefineT m () #

(Predicate p x, Typeable p) => Predicate (Not p) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Not p -> x -> RefineT m () #

(Foldable t, KnownNat n) => Predicate (SizeEqualTo n) (t a) # 
Instance details

Defined in Refined

Methods

validate :: Monad m => SizeEqualTo n -> t a -> RefineT m () #

(Foldable t, KnownNat n) => Predicate (SizeGreaterThan n) (t a) # 
Instance details

Defined in Refined

Methods

validate :: Monad m => SizeGreaterThan n -> t a -> RefineT m () #

(Foldable t, KnownNat n) => Predicate (SizeLessThan n) (t a) # 
Instance details

Defined in Refined

Methods

validate :: Monad m => SizeLessThan n -> t a -> RefineT m () #

(Ord x, Num x, KnownNat mn, KnownNat mx, mn <= mx) => Predicate (FromTo mn mx) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => FromTo mn mx -> x -> RefineT m () #

(Predicate l x, Predicate r x, Typeable l, Typeable r) => Predicate (Or l r) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Or l r -> x -> RefineT m () #

(Predicate l x, Predicate r x, Typeable l, Typeable r) => Predicate (And l r) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => And l r -> x -> RefineT m () #

Logical predicates

data Not p #

The negation of a predicate.

Instances
(Predicate p x, Typeable p) => Predicate (Not p) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Not p -> x -> RefineT m () #

data And l r #

The conjunction of two predicates.

Instances
(Predicate l x, Predicate r x, Typeable l, Typeable r) => Predicate (And l r) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => And l r -> x -> RefineT m () #

type (&&) = And infixr 3 #

The conjunction of two predicates.

data Or l r #

The disjunction of two predicates.

Instances
(Predicate l x, Predicate r x, Typeable l, Typeable r) => Predicate (Or l r) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Or l r -> x -> RefineT m () #

type (||) = Or infixr 2 #

The disjunction of two predicates.

Numeric predicates

data LessThan (n :: Nat) #

A Predicate ensuring that the value is less than the specified type-level number.

Instances
(Ord x, Num x, KnownNat n) => Predicate (LessThan n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => LessThan n -> x -> RefineT m () #

n <= m => Weaken (LessThan n) (To m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (LessThan n) x -> Refined (To m) x #

n <= m => Weaken (LessThan n) (LessThan m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (LessThan n) x -> Refined (LessThan m) x #

data GreaterThan (n :: Nat) #

A Predicate ensuring that the value is greater than the specified type-level number.

Instances
(Ord x, Num x, KnownNat n) => Predicate (GreaterThan n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => GreaterThan n -> x -> RefineT m () #

m <= n => Weaken (GreaterThan n) (From m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (GreaterThan n) x -> Refined (From m) x #

m <= n => Weaken (GreaterThan n) (GreaterThan m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (GreaterThan n) x -> Refined (GreaterThan m) x #

data From (n :: Nat) #

A Predicate ensuring that the value is greater than or equal to the specified type-level number.

Instances
(Ord x, Num x, KnownNat n) => Predicate (From n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => From n -> x -> RefineT m () #

m <= n => Weaken (From n) (From m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (From n) x -> Refined (From m) x #

m <= n => Weaken (GreaterThan n) (From m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (GreaterThan n) x -> Refined (From m) x #

p <= n => Weaken (FromTo n m) (From p) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (From p) x #

data To (n :: Nat) #

A Predicate ensuring that the value is less than or equal to the specified type-level number.

Instances
(Ord x, Num x, KnownNat n) => Predicate (To n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => To n -> x -> RefineT m () #

n <= m => Weaken (To n) (To m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (To n) x -> Refined (To m) x #

n <= m => Weaken (LessThan n) (To m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (LessThan n) x -> Refined (To m) x #

m <= q => Weaken (FromTo n m) (To q) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (To q) x #

data FromTo (mn :: Nat) (mx :: Nat) #

A Predicate ensuring that the value is within an inclusive range.

Instances
(Ord x, Num x, KnownNat mn, KnownNat mx, mn <= mx) => Predicate (FromTo mn mx) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => FromTo mn mx -> x -> RefineT m () #

m <= q => Weaken (FromTo n m) (To q) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (To q) x #

p <= n => Weaken (FromTo n m) (From p) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (From p) x #

(p <= n, m <= q) => Weaken (FromTo n m) (FromTo p q) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (FromTo p q) x #

data EqualTo (n :: Nat) #

A Predicate ensuring that the value is equal to the specified type-level number n.

Instances
(Eq x, Num x, KnownNat n) => Predicate (EqualTo n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => EqualTo n -> x -> RefineT m () #

data NotEqualTo (n :: Nat) #

A Predicate ensuring that the value is not equal to the specified type-level number n.

Instances
(Eq x, Num x, KnownNat n) => Predicate (NotEqualTo n) x # 
Instance details

Defined in Refined

Methods

validate :: Monad m => NotEqualTo n -> x -> RefineT m () #

type Positive = GreaterThan 0 #

A Predicate ensuring that the value is greater than zero.

type NonPositive = To 0 #

A Predicate ensuring that the value is less than or equal to zero.

type Negative = LessThan 0 #

A Predicate ensuring that the value is less than zero.

type NonNegative = From 0 #

A Predicate ensuring that the value is greater than or equal to zero.

type ZeroToOne = FromTo 0 1 #

An inclusive range of values from zero to one.

type NonZero = NotEqualTo 0 #

A Predicate ensuring that the value is not equal to zero.

Foldable predicates

data SizeLessThan (n :: Nat) #

A Predicate ensuring that the Foldable has a length which is less than the specified type-level number.

Instances
(Foldable t, KnownNat n) => Predicate (SizeLessThan n) (t a) # 
Instance details

Defined in Refined

Methods

validate :: Monad m => SizeLessThan n -> t a -> RefineT m () #

data SizeGreaterThan (n :: Nat) #

A Predicate ensuring that the Foldable has a length which is greater than the specified type-level number.

Instances
(Foldable t, KnownNat n) => Predicate (SizeGreaterThan n) (t a) # 
Instance details

Defined in Refined

Methods

validate :: Monad m => SizeGreaterThan n -> t a -> RefineT m () #

data SizeEqualTo (n :: Nat) #

A Predicate ensuring that the Foldable has a length which is equal to the specified type-level number.

Instances
(Foldable t, KnownNat n) => Predicate (SizeEqualTo n) (t a) # 
Instance details

Defined in Refined

Methods

validate :: Monad m => SizeEqualTo n -> t a -> RefineT m () #

type NonEmpty = SizeGreaterThan 0 #

A Predicate ensuring that the Foldable is non-empty.

IsList predicates

data Ascending #

A Predicate ensuring that the IsList contains elements in a strictly ascending order.

Instances
(IsList t, Ord (Item t)) => Predicate Ascending t # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Ascending -> t -> RefineT m () #

data Descending #

A Predicate ensuring that the IsList contains elements in a strictly descending order.

Instances
(IsList t, Ord (Item t)) => Predicate Descending t # 
Instance details

Defined in Refined

Methods

validate :: Monad m => Descending -> t -> RefineT m () #

Weakening

class Weaken from to where #

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 guarunteed to satisy 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.

Methods

weaken :: Refined from x -> Refined to x #

Instances
n <= m => Weaken (To n) (To m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (To n) x -> Refined (To m) x #

m <= n => Weaken (From n) (From m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (From n) x -> Refined (From m) x #

m <= n => Weaken (GreaterThan n) (From m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (GreaterThan n) x -> Refined (From m) x #

m <= n => Weaken (GreaterThan n) (GreaterThan m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (GreaterThan n) x -> Refined (GreaterThan m) x #

n <= m => Weaken (LessThan n) (To m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (LessThan n) x -> Refined (To m) x #

n <= m => Weaken (LessThan n) (LessThan m) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (LessThan n) x -> Refined (LessThan m) x #

m <= q => Weaken (FromTo n m) (To q) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (To q) x #

p <= n => Weaken (FromTo n m) (From p) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (From p) x #

(p <= n, m <= q) => Weaken (FromTo n m) (FromTo p q) # 
Instance details

Defined in Refined

Methods

weaken :: Refined (FromTo n m) x -> Refined (FromTo p q) x #

andLeft :: Refined (And l r) x -> Refined l x #

This function helps type inference. It is equivalent to the following:

instance Weaken (And l r) l

andRight :: Refined (And l r) x -> Refined r x #

This function helps type inference. It is equivalent to the following:

instance Weaken (And l r) r

leftOr :: Refined l x -> Refined (Or l r) x #

This function helps type inference. It is equivalent to the following:

instance Weaken l (Or l r)

rightOr :: Refined r x -> Refined (Or l r) x #

This function helps type inference. It is equivalent to the following:

instance Weaken r (Or l r)

Error handling

RefineException

data RefineException #

An exception encoding the way in which a Predicate failed.

Constructors

RefineNotException !TypeRep

A RefineException for failures involving the Not predicate.

RefineAndException !TypeRep !(These RefineException RefineException)

A RefineException for failures involving the And predicate.

RefineOrException !TypeRep !RefineException !RefineException

A RefineException for failures involving the Or predicate.

RefineOtherException !TypeRep !(Doc Void)

A RefineException for failures involving all other predicates.

Instances
Show RefineException # 
Instance details

Defined in Refined

Generic RefineException # 
Instance details

Defined in Refined

Associated Types

type Rep RefineException :: * -> * #

Exception RefineException #

Encode a RefineException for use with Control.Exception.

Instance details

Defined in Refined

Pretty RefineException #

Pretty-print a RefineException.

Instance details

Defined in Refined

Monad m => MonadError RefineException (RefineT m) # 
Instance details

Defined in Refined

type Rep RefineException # 
Instance details

Defined in Refined

type Rep RefineException = D1 (MetaData "RefineException" "Refined" "refined-0.2.3.0-GfyT7qaupVpJa2f41u1NLb" False) ((C1 (MetaCons "RefineNotException" PrefixI True) (S1 (MetaSel (Just "_RefineException_typeRep") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 TypeRep)) :+: C1 (MetaCons "RefineAndException" PrefixI True) (S1 (MetaSel (Just "_RefineException_typeRep") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 TypeRep) :*: S1 (MetaSel (Just "_RefineException_andChild") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (These RefineException RefineException)))) :+: (C1 (MetaCons "RefineOrException" PrefixI True) (S1 (MetaSel (Just "_RefineException_typeRep") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 TypeRep) :*: (S1 (MetaSel (Just "_RefineException_orLChild") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 RefineException) :*: S1 (MetaSel (Just "_RefineException_orRChild") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 RefineException))) :+: C1 (MetaCons "RefineOtherException" PrefixI True) (S1 (MetaSel (Just "_RefineException_typeRep") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 TypeRep) :*: S1 (MetaSel (Just "_RefineException_message") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Doc Void)))))

RefineT and RefineM

data RefineT m a #

A monad transformer that adds RefineExceptions to other monads.

The pure and return functions yield computations that produce the given value, while >>= sequences two subcomputations, exiting on the first RefineException.

Instances
MonadTrans RefineT # 
Instance details

Defined in Refined

Methods

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

Monad m => MonadError RefineException (RefineT m) # 
Instance details

Defined in Refined

Monad m => Monad (RefineT m) # 
Instance details

Defined in Refined

Methods

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

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

return :: a -> RefineT m a #

fail :: String -> RefineT m a #

Functor m => Functor (RefineT m) # 
Instance details

Defined in Refined

Methods

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

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

MonadFix m => MonadFix (RefineT m) # 
Instance details

Defined in Refined

Methods

mfix :: (a -> RefineT m a) -> RefineT m a #

Monad m => Applicative (RefineT m) # 
Instance details

Defined in Refined

Methods

pure :: a -> RefineT m a #

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

liftA2 :: (a -> b -> c) -> RefineT m a -> RefineT m b -> RefineT m c #

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

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

Generic1 (RefineT m :: * -> *) # 
Instance details

Defined in Refined

Associated Types

type Rep1 (RefineT m) :: k -> * #

Methods

from1 :: RefineT m a -> Rep1 (RefineT m) a #

to1 :: Rep1 (RefineT m) a -> RefineT m a #

Generic (RefineT m a) # 
Instance details

Defined in Refined

Associated Types

type Rep (RefineT m a) :: * -> * #

Methods

from :: RefineT m a -> Rep (RefineT m a) x #

to :: Rep (RefineT m a) x -> RefineT m a #

type Rep1 (RefineT m :: * -> *) # 
Instance details

Defined in Refined

type Rep1 (RefineT m :: * -> *) = D1 (MetaData "RefineT" "Refined" "refined-0.2.3.0-GfyT7qaupVpJa2f41u1NLb" True) (C1 (MetaCons "RefineT" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec1 (ExceptT RefineException m))))
type Rep (RefineT m a) # 
Instance details

Defined in Refined

type Rep (RefineT m a) = D1 (MetaData "RefineT" "Refined" "refined-0.2.3.0-GfyT7qaupVpJa2f41u1NLb" True) (C1 (MetaCons "RefineT" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (ExceptT RefineException m a))))

runRefineT :: RefineT m a -> m (Either RefineException a) #

The inverse of RefineT.

mapRefineT :: (m (Either RefineException a) -> n (Either RefineException b)) -> RefineT m a -> RefineT n b #

Map the unwrapped computation using the given function.

runRefineT (mapRefineT f m) = f (runRefineT m)

type RefineM a = RefineT Identity a #

RefineM a is equivalent to RefineT Identity a for any type a.

refineM :: Either RefineException a -> RefineM a #

Constructs a computation in the RefineM monad. (The inverse of runRefineM).

runRefineM :: RefineM a -> Either RefineException a #

Run a monadic action of type RefineM a, yielding an Either RefineException a.

This is just defined as runIdentity . runRefineT.

throwRefine :: Monad m => RefineException -> RefineT m a #

One can use throwRefine inside of a monadic context to begin processing a RefineException.

catchRefine :: Monad m => RefineT m a -> (RefineException -> RefineT m a) -> RefineT m a #

A handler function to handle previous RefineExceptions and return to normal execution. A common idiom is:

 do { action1; action2; action3 } `catchRefine' handler

where the action functions can call throwRefine. Note that handler and the do-block must have the same return type.

throwRefineOtherException #

Arguments

:: Monad m 
=> TypeRep

The TypeRep of the Predicate. This can usually be given by using typeOf.

-> Doc Void

A Doc Void encoding a custom error message to be pretty-printed.

-> RefineT m a 

A handler for a RefineException.

throwRefineOtherException is useful for defining what behaviour validate should have in the event of a predicate failure.