validity 0.3.0.2 → 0.3.0.3
raw patch · 3 files changed
+79/−27 lines, 3 filesdep ~base
Dependency ranges changed: base
Files
- src/Data/RelativeValidity.hs +5/−2
- src/Data/Validity.hs +71/−22
- validity.cabal +3/−3
src/Data/RelativeValidity.hs view
@@ -1,11 +1,12 @@-{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-| Relative validity- -}+ -} module Data.RelativeValidity ( RelativeValidity(..)+ , isInvalidFor ) where @@ -20,3 +21,5 @@ class RelativeValidity a b where isValidFor :: a -> b -> Bool +isInvalidFor :: RelativeValidity a b => a -> b -> Bool+isInvalidFor a b = not $ isValidFor a b
src/Data/Validity.hs view
@@ -2,42 +2,49 @@ {-| - @Validity@ is used to specify additional invariants upon values that are not- enforced by the type system.+ @Validity@ is used to specify additional invariants upon values that are not+ enforced by the type system. - Let's take an example.- Suppose we were to implement a type @Prime@ that represents prime integers.+ Let's take an example.+ Suppose we were to implement a type @Prime@ that represents prime integers. - If you were to completely enforce the invariant that the represented number is- a prime, then we could use @Numeric.Natural@ and only store the index of the- given prime in the infinite sequence of prime numbers.- This is very safe but also very expensive if we ever want to use the number,- because we would have to calculcate all the prime numbers until that index.+ If you were to completely enforce the invariant that the represented number is+ a prime, then we could use @Numeric.Natural@ and only store the index of the+ given prime in the infinite sequence of prime numbers.+ This is very safe but also very expensive if we ever want to use the number,+ because we would have to calculcate all the prime numbers until that index. - Instead we choose to implement @Prime@ by a @newtype Prime = Prime Int@.- Now we have to maintain the invariant that the @Int@ that we use to represent- the prime is in fact positive and a prime.+ Instead we choose to implement @Prime@ by a @newtype Prime = Prime Int@.+ Now we have to maintain the invariant that the @Int@ that we use to represent+ the prime is in fact positive and a prime. - The @Validity@ typeclass allows us to specify this invariant (and enables- testing via the @genvalidity@ libraries:- https://hackage.haskell.org/package/genvalidity ):+ The @Validity@ typeclass allows us to specify this invariant (and enables+ testing via the @genvalidity@ libraries:+ https://hackage.haskell.org/package/genvalidity ): - > instance Validity Prime where- > isValid (Prime n) = isPrime n- -}+ > instance Validity Prime where+ > isValid (Prime n) = isPrime n+ -} module Data.Validity ( Validity(..)+ , isInvalid , constructValid , constructValidUnsafe ) where +import Data.Maybe (fromMaybe) + -- | A class of types that have additional invariants defined upon them -- that aren't enforced by the type system class Validity a where+ -- | Check whether a given value is a valid value. isValid :: a -> Bool +isInvalid :: Validity a => a -> Bool+isInvalid = not . isValid+ -- | Any tuple of things is valid if both of its elements are valid instance (Validity a, Validity b) => Validity (a, b) where isValid (a, b) = isValid a && isValid b@@ -62,7 +69,52 @@ isValid Nothing = True isValid (Just a) = isValid a +-- | Trivially valid+instance Validity () where+ isValid = const True +-- | Trivially valid+instance Validity Bool where+ isValid = const True++-- | Trivially valid+instance Validity Ordering where+ isValid = const True++-- | Trivially valid+instance Validity Char where+ isValid = const True++-- | Trivially valid+instance Validity Int where+ isValid = const True++-- | Trivially valid+instance Validity Word where+ isValid = const True++-- | NOT trivially valid:+--+-- * NaN is not valid.+-- * Infinite values are not valid.+instance Validity Float where+ isValid d+ = not (isNaN d)+ && not (isInfinite d)++-- | NOT trivially valid:+--+-- * NaN is not valid.+-- * Infinite values are not valid.+instance Validity Double where+ isValid d+ = not (isNaN d)+ && not (isInfinite d)++-- | Trivially valid+instance Validity Integer where+ isValid = const True+ -- | Construct a valid element from an unchecked element constructValid :: Validity a => a -> Maybe a constructValid p = if isValid p then Just p else Nothing@@ -70,8 +122,5 @@ -- | Construct a valid element from an unchecked element, throwing 'error' -- on invalid elements. constructValidUnsafe :: (Show a, Validity a) => a -> a-constructValidUnsafe p =- case constructValid p of- Nothing -> error $ show p ++ " is not valid"- Just p -> p+constructValidUnsafe p = fromMaybe (error $ show p ++ " is not valid") $ constructValid p
validity.cabal view
@@ -1,11 +1,11 @@ name: validity-version: 0.3.0.2+version: 0.3.0.3 synopsis: Validity typeclass-description: +description: Note: There are companion instance packages for this library: . * <https://hackage.haskell.org/package/validity-text validity-text>- . + . * <https://hackage.haskell.org/package/validity-containers validity-containers> homepage: https://github.com/NorfairKing/validity#readme