-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Refinement types with static and runtime checking -- -- For an extensive introduction to the library please follow to this -- blog-post. @package refined @version 0.4.2 -- | This module is defined internally to avoid using the these -- package, which brings in a lot of very heavy and unnecessary -- transitive dependencies. We export the type and constructors here, in -- case a user should need it. We provide a small API for working with -- the These type here. If one should need a fuller API, see -- https://hackage.haskell.org/package/these Converting to/from -- the two types should be trivial, as the data constructors are exported -- from both. module Refined.These -- | This is defined internally to avoid using the these package, -- which brings in a lot of very heavy and unnecessary transitive -- dependencies. We export the type and constructors here, in case a user -- should need it. data These a b This :: a -> These a b That :: b -> These a b These :: a -> b -> These a b -- | Case analysis for the These type. these :: (a -> c) -> (b -> c) -> (a -> b -> c) -> These a b -> c -- | Takes two default values and produces a tuple. fromThese :: a -> b -> These a b -> (a, b) -- | Coalesce with the provided operation. mergeThese :: (a -> a -> a) -> These a a -> a -- | BiMap and coalesce results with the provided operation. mergeTheseWith :: (a -> c) -> (b -> c) -> (c -> c -> c) -> These a b -> c -- | A Traversal of the first half of a These, suitable for -- use with Control.Lens. here :: Applicative f => (a -> f b) -> These a t -> f (These b t) -- | A Traversal of the second half of a These, suitable -- for use with Control.Lens. there :: Applicative f => (a -> f b) -> These t a -> f (These t b) -- |
-- justThis = these Just (_ -> Nothing) (_ _ -> Nothing) --justThis :: These a b -> Maybe a -- |
-- justThat = these (_ -> Nothing) Just (_ _ -> Nothing) --justThat :: These a b -> Maybe b -- |
-- justThese = these (_ -> Nothing) (_ -> Nothing) (a b -> Just (a, b)) --justThese :: These a b -> Maybe (a, b) -- | Select all This constructors from a list. catThis :: [These a b] -> [a] -- | Select all That constructors from a list. catThat :: [These a b] -> [b] -- | Select all These constructors from a list. catThese :: [These a b] -> [(a, b)] -- | Select each constructor and partition them into separate lists. partitionThese :: [These a b] -> ([(a, b)], ([a], [b])) -- |
-- isThis = isJust . justThis --isThis :: These a b -> Bool -- |
-- isThat = isJust . justThat --isThat :: These a b -> Bool -- |
-- isThese = isJust . justThese --isThese :: These a b -> Bool -- | Bifunctor map. mapThese :: (a -> c) -> (b -> d) -> These a b -> These c d -- |
-- mapThis = over here --mapThis :: (a -> c) -> These a b -> These c b -- |
-- mapThat = over there --mapThat :: (b -> d) -> These a b -> These a d instance GHC.Generics.Generic1 (Refined.These.These a) instance GHC.Generics.Generic (Refined.These.These a b) instance (Data.Data.Data a, Data.Data.Data b) => Data.Data.Data (Refined.These.These a b) instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Refined.These.These a b) instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Refined.These.These a b) instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Refined.These.These a b) instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Refined.These.These a b) instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b) => GHC.Base.Semigroup (Refined.These.These a b) instance Data.Bifunctor.Bifunctor Refined.These.These instance GHC.Base.Functor (Refined.These.These a) instance GHC.Base.Semigroup a => GHC.Base.Applicative (Refined.These.These a) instance GHC.Base.Semigroup a => GHC.Base.Monad (Refined.These.These a) instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b) => Control.DeepSeq.NFData (Refined.These.These a b) instance Data.Foldable.Foldable (Refined.These.These a) instance Data.Traversable.Traversable (Refined.These.These a) instance Data.Bifoldable.Bifoldable Refined.These.These -- | 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/ module Refined.Internal -- | A refinement type, which wraps a value of type x, ensuring -- that it satisfies a type-level predicate p. newtype Refined p x Refined :: x -> Refined p x -- | A smart constructor of a Refined value. Checks the input value -- at runtime. refine :: Predicate p x => x -> Either RefineException (Refined p x) -- | Constructs a Refined value at run-time, calling throwM -- if the value does not satisfy the predicate. refineThrow :: (Predicate p x, MonadThrow m) => x -> m (Refined p x) -- | Constructs a Refined value at run-time, calling fail 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 -- throwError 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 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. -- -- It may be useful to use this function with the `th-lift-instances` -- package at -- https://hackage.haskell.org/package/th-lift-instances/ refineTH :: (Predicate p x, Lift x) => x -> Q (TExp (Refined p x)) -- | Extracts the refined value. unrefine :: Refined p x -> x -- | A typeclass which defines a runtime interpretation of a type-level -- predicate p for type x. class (Typeable p) => Predicate p x -- | Check the value x according to the predicate p, -- producing an error string if the value does not satisfy. validate :: (Predicate p x, Monad m) => p -> x -> RefineT m () -- | The negation of a predicate. -- --
-- >>> isRight (refine @(Not NonEmpty) @[Int] []) -- True ---- --
-- >>> isLeft (refine @(Not NonEmpty) @[Int] [1,2]) -- True --data Not p Not :: Not p -- | The conjunction of two predicates. -- --
-- >>> isLeft (refine @(And Positive Negative) @Int 3) -- True ---- --
-- >>> isRight (refine @(And Positive Odd) @Int 203) -- True --data And l r And :: And l r -- | The conjunction of two predicates. type (&&) = And infixr 3 && -- | The disjunction of two predicates. -- --
-- >>> isRight (refine @(Or Even Odd) @Int 3) -- True ---- --
-- >>> isRight (refine @(Or (LessThan 3) (GreaterThan 3)) @Int 2) -- True --data Or l r Or :: Or l r -- | The disjunction of two predicates. type (||) = Or infixr 2 || -- | A predicate which is satisfied for all types. The value is not -- evaluated by validate. -- --
-- >>> isRight (refine @IdPred @Int undefined) -- True ---- --
-- >>> isLeft (refine @IdPred @Int undefined) -- False --data IdPred IdPred :: IdPred -- | 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 --data LessThan (n :: Nat) LessThan :: LessThan -- | 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 --data GreaterThan (n :: Nat) GreaterThan :: GreaterThan -- | 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 --data From (n :: Nat) From :: From -- | 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 --data To (n :: Nat) To :: To -- | 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 --data FromTo (mn :: Nat) (mx :: Nat) FromTo :: FromTo -- | 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 --data NegativeFromTo (n :: Nat) (m :: Nat) NegativeFromTo :: NegativeFromTo -- | 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 --data EqualTo (n :: Nat) EqualTo :: EqualTo -- | 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 --data NotEqualTo (n :: Nat) NotEqualTo :: NotEqualTo -- | A Predicate ensuring that the value is odd. -- --
-- >>> isRight (refine @Odd @Int 33) -- True ---- --
-- >>> isLeft (refine @Odd @Int 32) -- True --data Odd Odd :: Odd -- | A Predicate ensuring that the value is even. -- --
-- >>> isRight (refine @Even @Int 32) -- True ---- --
-- >>> isLeft (refine @Even @Int 33) -- True --data Even Even :: Even -- | A Predicate ensuring that the value is divisible by n. -- That is to say, m mod natVal (Proxy n) -- == 0@ -- --
-- >>> isRight (refine @(DivisibleBy 3) @Int 12) -- True ---- --
-- >>> isLeft (refine @(DivisibleBy 2) @Int 37) -- True --data DivisibleBy (n :: Nat) DivisibleBy :: DivisibleBy -- | A Predicate ensuring that the value is greater than zero. type Positive = GreaterThan 0 -- | A Predicate ensuring that the value is less than or equal to -- zero. type NonPositive = To 0 -- | A Predicate ensuring that the value is less than zero. type Negative = LessThan 0 -- | A Predicate ensuring that the value is greater than or equal to -- zero. type NonNegative = From 0 -- | An inclusive range of values from zero to one. type ZeroToOne = FromTo 0 1 -- | A Predicate ensuring that the value is not equal to zero. type NonZero = NotEqualTo 0 -- | A Predicate ensuring that the Foldable 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 --data SizeLessThan (n :: Nat) SizeLessThan :: SizeLessThan -- | A Predicate ensuring that the Foldable 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 --data SizeGreaterThan (n :: Nat) SizeGreaterThan :: SizeGreaterThan -- | A Predicate ensuring that the Foldable 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 --data SizeEqualTo (n :: Nat) SizeEqualTo :: SizeEqualTo -- | A Predicate ensuring that the Foldable is non-empty. type NonEmpty = SizeGreaterThan 0 -- | 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 --data Ascending Ascending :: Ascending -- | 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 --data Descending Descending :: Descending -- | 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. class Weaken from to weaken :: Weaken from to => Refined from x -> Refined to x -- | This function helps type inference. It is equivalent to the following: -- --
-- instance Weaken (And l r) l --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) r --andRight :: Refined (And l r) x -> Refined r x -- | This function helps type inference. It is equivalent to the following: -- --
-- instance Weaken l (Or l r) --leftOr :: Refined l x -> Refined (Or l r) x -- | This function helps type inference. It is equivalent to the following: -- --
-- instance Weaken r (Or l r) --rightOr :: Refined r x -> Refined (Or l r) x -- | An exception encoding the way in which a Predicate failed. data RefineException -- | A RefineException for failures involving the Not -- predicate. RefineNotException :: !TypeRep -> RefineException -- | A RefineException for failures involving the And -- predicate. RefineAndException :: !TypeRep -> !These RefineException RefineException -> RefineException -- | A RefineException for failures involving the Or -- predicate. RefineOrException :: !TypeRep -> !RefineException -> !RefineException -> RefineException -- | A RefineException for failures involving all other predicates. RefineOtherException :: !TypeRep -> !Doc Void -> RefineException -- | Display a RefineException as a Doc ann displayRefineException :: RefineException -> Doc ann -- | 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. data RefineT m a -- | The inverse of RefineT. runRefineT :: RefineT m a -> m (Either RefineException a) -- | Map the unwrapped computation using the given function. -- --
-- runRefineT (mapRefineT f m) = f (runRefineT m) --mapRefineT :: (m (Either RefineException a) -> n (Either RefineException b)) -> RefineT m a -> RefineT n b -- | RefineM a is equivalent to RefineT -- Identity a for any type a. type RefineM a = RefineT Identity a -- | Constructs a computation in the RefineM monad. (The inverse of -- runRefineM). refineM :: Either RefineException a -> RefineM a -- | Run a monadic action of type RefineM a, yielding an -- Either RefineException a. -- -- This is just defined as runIdentity . -- runRefineT. runRefineM :: RefineM a -> Either RefineException a -- | One can use throwRefine inside of a monadic context to -- begin processing a RefineException. throwRefine :: Monad m => RefineException -> 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.
catchRefine :: Monad m => RefineT m a -> (RefineException -> RefineT m a) -> 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.
throwRefineOtherException :: Monad m => TypeRep -> Doc Void -> RefineT m a
-- | Helper function, stolen from the flow package.
(|>) :: a -> (a -> b) -> b
infixl 0 |>
-- | Helper function, stolen from the flow package.
(.>) :: (a -> b) -> (b -> c) -> a -> c
infixl 9 .>
-- | -- >>> pretty 1 <+> pretty "hello" <+> pretty 1.234 -- 1 hello 1.234 --pretty :: Pretty a => a -> Doc ann instance GHC.Generics.Generic1 (Refined.Internal.RefineT m) instance GHC.Generics.Generic (Refined.Internal.RefineT m a) instance Control.Monad.Trans.Class.MonadTrans Refined.Internal.RefineT instance GHC.Base.Monad m => Control.Monad.Error.Class.MonadError Refined.Internal.RefineException (Refined.Internal.RefineT m) instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Refined.Internal.RefineT m) instance GHC.Base.Monad m => GHC.Base.Monad (Refined.Internal.RefineT m) instance GHC.Base.Monad m => GHC.Base.Applicative (Refined.Internal.RefineT m) instance GHC.Base.Functor m => GHC.Base.Functor (Refined.Internal.RefineT m) instance GHC.Generics.Generic Refined.Internal.RefineException instance GHC.Generics.Generic Refined.Internal.Even instance GHC.Generics.Generic Refined.Internal.Odd instance GHC.Generics.Generic (Refined.Internal.DivisibleBy n) instance GHC.Generics.Generic (Refined.Internal.NegativeFromTo n m) instance GHC.Generics.Generic (Refined.Internal.NotEqualTo n) instance GHC.Generics.Generic (Refined.Internal.EqualTo n) instance GHC.Generics.Generic (Refined.Internal.FromTo mn mx) instance GHC.Generics.Generic (Refined.Internal.To n) instance GHC.Generics.Generic (Refined.Internal.From n) instance GHC.Generics.Generic (Refined.Internal.GreaterThan n) instance GHC.Generics.Generic (Refined.Internal.LessThan n) instance GHC.Generics.Generic Refined.Internal.Descending instance GHC.Generics.Generic Refined.Internal.Ascending instance GHC.Generics.Generic (Refined.Internal.SizeEqualTo n) instance GHC.Generics.Generic (Refined.Internal.SizeGreaterThan n) instance GHC.Generics.Generic (Refined.Internal.SizeLessThan n) instance GHC.Generics.Generic1 (Refined.Internal.Or l) instance GHC.Generics.Generic (Refined.Internal.Or l r) instance GHC.Generics.Generic1 (Refined.Internal.And l) instance GHC.Generics.Generic (Refined.Internal.And l r) instance GHC.Generics.Generic1 Refined.Internal.Not instance GHC.Generics.Generic (Refined.Internal.Not p) instance GHC.Generics.Generic Refined.Internal.IdPred instance GHC.Show.Show x => GHC.Show.Show (Refined.Internal.Refined p x) instance GHC.Classes.Ord x => GHC.Classes.Ord (Refined.Internal.Refined p x) instance Data.Foldable.Foldable (Refined.Internal.Refined p) instance GHC.Classes.Eq x => GHC.Classes.Eq (Refined.Internal.Refined p x) instance (GHC.Read.Read x, Refined.Internal.Predicate p x) => GHC.Read.Read (Refined.Internal.Refined p x) instance Refined.Internal.Predicate Refined.Internal.IdPred x instance (Refined.Internal.Predicate p x, Data.Typeable.Internal.Typeable p) => Refined.Internal.Predicate (Refined.Internal.Not p) x instance (Refined.Internal.Predicate l x, Refined.Internal.Predicate r x, Data.Typeable.Internal.Typeable l, Data.Typeable.Internal.Typeable r) => Refined.Internal.Predicate (Refined.Internal.And l r) x instance (Refined.Internal.Predicate l x, Refined.Internal.Predicate r x, Data.Typeable.Internal.Typeable l, Data.Typeable.Internal.Typeable r) => Refined.Internal.Predicate (Refined.Internal.Or l r) x instance (Data.Foldable.Foldable t, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.SizeLessThan n) (t a) instance (Data.Foldable.Foldable t, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.SizeGreaterThan n) (t a) instance (Data.Foldable.Foldable t, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.SizeEqualTo n) (t a) instance (Data.Foldable.Foldable t, GHC.Classes.Ord a) => Refined.Internal.Predicate Refined.Internal.Ascending (t a) instance (Data.Foldable.Foldable t, GHC.Classes.Ord a) => Refined.Internal.Predicate Refined.Internal.Descending (t a) instance (GHC.Classes.Ord x, GHC.Num.Num x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.LessThan n) x instance (GHC.Classes.Ord x, GHC.Num.Num x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.GreaterThan n) x instance (GHC.Classes.Ord x, GHC.Num.Num x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.From n) x instance (GHC.Classes.Ord x, GHC.Num.Num x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.To n) x instance (GHC.Classes.Ord x, GHC.Num.Num x, GHC.TypeNats.KnownNat mn, GHC.TypeNats.KnownNat mx, mn GHC.TypeNats.<= mx) => Refined.Internal.Predicate (Refined.Internal.FromTo mn mx) x instance (GHC.Classes.Eq x, GHC.Num.Num x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.EqualTo n) x instance (GHC.Classes.Eq x, GHC.Num.Num x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.NotEqualTo n) x instance (GHC.Classes.Ord x, GHC.Num.Num x, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => Refined.Internal.Predicate (Refined.Internal.NegativeFromTo n m) x instance (GHC.Real.Integral x, GHC.TypeNats.KnownNat n) => Refined.Internal.Predicate (Refined.Internal.DivisibleBy n) x instance GHC.Real.Integral x => Refined.Internal.Predicate Refined.Internal.Odd x instance GHC.Real.Integral x => Refined.Internal.Predicate Refined.Internal.Even x instance GHC.Show.Show Refined.Internal.RefineException instance Data.Text.Prettyprint.Doc.Internal.Pretty Refined.Internal.RefineException instance GHC.Exception.Type.Exception Refined.Internal.RefineException instance (n GHC.TypeNats.<= m) => Refined.Internal.Weaken (Refined.Internal.LessThan n) (Refined.Internal.LessThan m) instance (n GHC.TypeNats.<= m) => Refined.Internal.Weaken (Refined.Internal.LessThan n) (Refined.Internal.To m) instance (n GHC.TypeNats.<= m) => Refined.Internal.Weaken (Refined.Internal.To n) (Refined.Internal.To m) instance (m GHC.TypeNats.<= n) => Refined.Internal.Weaken (Refined.Internal.GreaterThan n) (Refined.Internal.GreaterThan m) instance (m GHC.TypeNats.<= n) => Refined.Internal.Weaken (Refined.Internal.GreaterThan n) (Refined.Internal.From m) instance (m GHC.TypeNats.<= n) => Refined.Internal.Weaken (Refined.Internal.From n) (Refined.Internal.From m) instance (p GHC.TypeNats.<= n, m GHC.TypeNats.<= q) => Refined.Internal.Weaken (Refined.Internal.FromTo n m) (Refined.Internal.FromTo p q) instance (p GHC.TypeNats.<= n) => Refined.Internal.Weaken (Refined.Internal.FromTo n m) (Refined.Internal.From p) instance (m GHC.TypeNats.<= q) => Refined.Internal.Weaken (Refined.Internal.FromTo n m) (Refined.Internal.To q) instance Language.Haskell.TH.Syntax.Lift x => Language.Haskell.TH.Syntax.Lift (Refined.Internal.Refined p x) -- | This module exposes orphan instances for the Refined type. This -- is unavoidable given the current module structure. module Refined.Orphan.QuickCheck instance (Test.QuickCheck.Arbitrary.Arbitrary a, Refined.Internal.Predicate p a) => Test.QuickCheck.Arbitrary.Arbitrary (Refined.Internal.Refined p a) -- | This module exposes orphan instances for the Refined type. This -- is unavoidable given the current module structure. module Refined.Orphan.Aeson instance (Data.Aeson.Types.FromJSON.FromJSON a, Refined.Internal.Predicate p a) => Data.Aeson.Types.FromJSON.FromJSON (Refined.Internal.Refined p a) instance (Data.Aeson.Types.ToJSON.ToJSON a, Refined.Internal.Predicate p a) => Data.Aeson.Types.ToJSON.ToJSON (Refined.Internal.Refined p a) -- | This module exposes orphan instances for the Refined type. -- This is unavoidable given the current module structure. module Refined.Orphan -- | 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/ -- -- This module only provides safe constructions of Refined -- values, safe meaning that the refinement predicate holds, and -- the construction of the Refined value is total. -- -- If you can manually prove that the refinement predicate holds, or you -- do not necessarily care about this definition of safety, use the -- module Refined.Unsafe. module Refined -- | A refinement type, which wraps a value of type x, ensuring -- that it satisfies a type-level predicate p. data Refined p x -- | A smart constructor of a Refined value. Checks the input value -- at runtime. refine :: Predicate p x => x -> Either RefineException (Refined p x) -- | Constructs a Refined value at run-time, calling throwM -- if the value does not satisfy the predicate. refineThrow :: (Predicate p x, MonadThrow m) => x -> m (Refined p x) -- | Constructs a Refined value at run-time, calling fail 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 -- throwError 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 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. -- -- It may be useful to use this function with the `th-lift-instances` -- package at -- https://hackage.haskell.org/package/th-lift-instances/ refineTH :: (Predicate p x, Lift x) => x -> Q (TExp (Refined p x)) -- | Extracts the refined value. unrefine :: Refined p x -> x -- | A typeclass which defines a runtime interpretation of a type-level -- predicate p for type x. class (Typeable p) => Predicate p x -- | Check the value x according to the predicate p, -- producing an error string if the value does not satisfy. validate :: (Predicate p x, Monad m) => p -> x -> RefineT m () -- | The negation of a predicate. -- --
-- >>> isRight (refine @(Not NonEmpty) @[Int] []) -- True ---- --
-- >>> isLeft (refine @(Not NonEmpty) @[Int] [1,2]) -- True --data Not p -- | The conjunction of two predicates. -- --
-- >>> isLeft (refine @(And Positive Negative) @Int 3) -- True ---- --
-- >>> isRight (refine @(And Positive Odd) @Int 203) -- True --data And l r -- | The conjunction of two predicates. type (&&) = And infixr 3 && -- | The disjunction of two predicates. -- --
-- >>> isRight (refine @(Or Even Odd) @Int 3) -- True ---- --
-- >>> isRight (refine @(Or (LessThan 3) (GreaterThan 3)) @Int 2) -- True --data Or l r -- | The disjunction of two predicates. type (||) = Or infixr 2 || -- | A predicate which is satisfied for all types. The value is not -- evaluated by validate. -- --
-- >>> isRight (refine @IdPred @Int undefined) -- True ---- --
-- >>> isLeft (refine @IdPred @Int undefined) -- False --data IdPred -- | 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 --data LessThan (n :: Nat) -- | 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 --data GreaterThan (n :: Nat) -- | 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 --data From (n :: Nat) -- | 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 --data To (n :: Nat) -- | 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 --data FromTo (mn :: Nat) (mx :: Nat) -- | 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 --data EqualTo (n :: Nat) -- | 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 --data NotEqualTo (n :: Nat) -- | A Predicate ensuring that the value is greater than zero. type Positive = GreaterThan 0 -- | A Predicate ensuring that the value is less than or equal to -- zero. type NonPositive = To 0 -- | A Predicate ensuring that the value is less than zero. type Negative = LessThan 0 -- | A Predicate ensuring that the value is greater than or equal to -- zero. type NonNegative = From 0 -- | An inclusive range of values from zero to one. type ZeroToOne = FromTo 0 1 -- | A Predicate ensuring that the value is not equal to zero. type NonZero = NotEqualTo 0 -- | A Predicate ensuring that the Foldable 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 --data SizeLessThan (n :: Nat) -- | A Predicate ensuring that the Foldable 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 --data SizeGreaterThan (n :: Nat) -- | A Predicate ensuring that the Foldable 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 --data SizeEqualTo (n :: Nat) -- | A Predicate ensuring that the Foldable is non-empty. type NonEmpty = SizeGreaterThan 0 -- | 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 --data Ascending -- | 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 --data Descending -- | 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. class Weaken from to weaken :: Weaken from to => Refined from x -> Refined to x -- | This function helps type inference. It is equivalent to the following: -- --
-- instance Weaken (And l r) l --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) r --andRight :: Refined (And l r) x -> Refined r x -- | This function helps type inference. It is equivalent to the following: -- --
-- instance Weaken l (Or l r) --leftOr :: Refined l x -> Refined (Or l r) x -- | This function helps type inference. It is equivalent to the following: -- --
-- instance Weaken r (Or l r) --rightOr :: Refined r x -> Refined (Or l r) x -- | An exception encoding the way in which a Predicate failed. data RefineException -- | A RefineException for failures involving the Not -- predicate. RefineNotException :: !TypeRep -> RefineException -- | A RefineException for failures involving the And -- predicate. RefineAndException :: !TypeRep -> !These RefineException RefineException -> RefineException -- | A RefineException for failures involving the Or -- predicate. RefineOrException :: !TypeRep -> !RefineException -> !RefineException -> RefineException -- | A RefineException for failures involving all other predicates. RefineOtherException :: !TypeRep -> !Doc Void -> RefineException -- | Display a RefineException as a Doc ann displayRefineException :: RefineException -> Doc ann -- | 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. data RefineT m a -- | The inverse of RefineT. runRefineT :: RefineT m a -> m (Either RefineException a) -- | Map the unwrapped computation using the given function. -- --
-- runRefineT (mapRefineT f m) = f (runRefineT m) --mapRefineT :: (m (Either RefineException a) -> n (Either RefineException b)) -> RefineT m a -> RefineT n b -- | RefineM a is equivalent to RefineT -- Identity a for any type a. type RefineM a = RefineT Identity a -- | Constructs a computation in the RefineM monad. (The inverse of -- runRefineM). refineM :: Either RefineException a -> RefineM a -- | Run a monadic action of type RefineM a, yielding an -- Either RefineException a. -- -- This is just defined as runIdentity . -- runRefineT. runRefineM :: RefineM a -> Either RefineException a -- | One can use throwRefine inside of a monadic context to -- begin processing a RefineException. throwRefine :: Monad m => RefineException -> 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.
catchRefine :: Monad m => RefineT m a -> (RefineException -> RefineT m a) -> 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.
throwRefineOtherException :: Monad m => TypeRep -> Doc Void -> RefineT m a
-- | -- >>> pretty 1 <+> pretty "hello" <+> pretty 1.234 -- 1 hello 1.234 --pretty :: Pretty a => a -> Doc ann -- | This module exposes unsafe refinements. An unsafe -- refinement is one which either does not make the guarantee of totality -- in construction of the Refined value or does not perform a -- check of the refinement predicate. It is recommended only to use this -- when you can manually prove that the refinement predicate holds. module Refined.Unsafe -- | A refinement type, which wraps a value of type x, ensuring -- that it satisfies a type-level predicate p. data Refined p x -- | Constructs a Refined value, completely ignoring any -- refinements! Use this only when you can manually prove that the -- refinement holds. reallyUnsafeRefine :: 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! unsafeRefine :: Predicate p x => x -> Refined p x -- | A coercion between a type and any refinement of that type. See -- Data.Type.Coercion for functions manipulating coercions. reallyUnsafeUnderlyingRefined :: Coercion x (Refined p x) -- | Reveal that x and Refined p x are -- Coercible for all x and p -- simultaneously. -- --
-- reallyUnsafePredEquiv :: Coercion (Refined p x) (Refined q x) -- reallyUnsafePredEquiv = reallyUnsafeAllUnderlyingRefined Coercion --reallyUnsafeAllUnderlyingRefined :: (forall x y p. Coercible x y => Coercible y (Refined p x) => r) -> r -- | A coercion between two Refined types, magicking up the claim -- that one predicate is entirely equivalent to another. reallyUnsafePredEquiv :: Coercion (Refined p x) (Refined q x) -- | This module exports the Refined type with its constructor. This -- is very risky! In particular, the Coercible instances will be -- visible throughout the importing module. It is usually better to build -- the necessary coercions locally using the utilities in -- Refined.Unsafe, but in some cases it may be more convenient to -- write a separate module that imports this one and exports some large -- coercion. module Refined.Unsafe.Type -- | A refinement type, which wraps a value of type x, ensuring -- that it satisfies a type-level predicate p. newtype Refined p x Refined :: x -> Refined p x