-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Validity typeclass
--   
--   For more info, see <a>the readme</a>.
--   
--   Note: There are companion instance packages for this library:
--   
--   <ul>
--   <li><a>validity-text</a></li>
--   <li><a>validity-path</a></li>
--   <li><a>validity-time</a></li>
--   <li><a>validity-containers</a></li>
--   <li><a>validity-bytestring</a></li>
--   </ul>
@package validity
@version 0.3.3.0


-- | <tt>Validity</tt> 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
--   <tt>Prime</tt> that represents prime integers.
--   
--   If you were to completely enforce the invariant that the represented
--   number is a prime, then we could use <a>Natural</a> 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 <tt>Prime</tt> by a <tt>newtype Prime =
--   Prime Int</tt>. Now we have to maintain the invariant that the
--   <tt>Int</tt> that we use to represent the prime is in fact positive
--   and a prime.
--   
--   The <tt>Validity</tt> typeclass allows us to specify this invariant
--   (and enables testing via the <tt>genvalidity</tt> libraries:
--   <a>https://hackage.haskell.org/package/genvalidity</a> ):
--   
--   <pre>
--   instance Validity Prime where
--       isValid (Prime n) = isPrime n
--   </pre>
--   
--   If certain typeclass invariants exist, you can make these explicit in
--   the validity instance as well. For example, 'Fixed a' is only valid if
--   <tt>a</tt> has an <a>HasResolution</a> instance, so the correct
--   validity instance is <tt>HasResolution a =&gt; Validity (Fixed
--   a)</tt>.
module Data.Validity

-- | A class of types that have additional invariants defined upon them
--   that aren't enforced by the type system
--   
--   <a>isValid</a> should be an underapproximation of actual validity.
--   
--   This means that if <a>isValid</a> is not a perfect representation of
--   actual validity, for safety reasons, it should never return
--   <a>True</a> for invalid values, but it may return <a>False</a> for
--   valid values.
--   
--   For example:
--   
--   <pre>
--   isValid = const False
--   </pre>
--   
--   is a valid implementation for any type, because it never returns
--   <a>True</a> for invalid values.
--   
--   <pre>
--   isValid (Even i) = i == 2
--   </pre>
--   
--   is a valid implementation for <tt>newtype Even = Even Int</tt>, but
--   
--   <pre>
--   isValid (Even i) = even i || i == 1
--   </pre>
--   
--   is not because it returns <a>True</a> for an invalid value: '1'.
class Validity a where isValid = gIsValid . from
isValid :: Validity a => a -> Bool
isValid :: (Validity a, Generic a, GValidity (Rep a)) => a -> Bool
isInvalid :: Validity a => a -> Bool

-- | Construct a valid element from an unchecked element
constructValid :: Validity a => a -> Maybe a

-- | Construct a valid element from an unchecked element, throwing
--   <a>error</a> on invalid elements.
constructValidUnsafe :: (Show a, Validity a) => a -> a
instance (Data.Validity.Validity a, Data.Validity.Validity b) => Data.Validity.Validity (a, b)
instance (Data.Validity.Validity a, Data.Validity.Validity b) => Data.Validity.Validity (Data.Either.Either a b)
instance (Data.Validity.Validity a, Data.Validity.Validity b, Data.Validity.Validity c) => Data.Validity.Validity (a, b, c)
instance Data.Validity.Validity a => Data.Validity.Validity [a]
instance Data.Validity.Validity a => Data.Validity.Validity (GHC.Base.Maybe a)
instance Data.Validity.Validity ()
instance Data.Validity.Validity GHC.Types.Bool
instance Data.Validity.Validity GHC.Types.Ordering
instance Data.Validity.Validity GHC.Types.Char
instance Data.Validity.Validity GHC.Types.Int
instance Data.Validity.Validity GHC.Types.Word
instance Data.Validity.Validity GHC.Word.Word8
instance Data.Validity.Validity GHC.Word.Word16
instance Data.Validity.Validity GHC.Types.Float
instance Data.Validity.Validity GHC.Types.Double
instance Data.Validity.Validity GHC.Integer.Type.Integer
instance Data.Validity.Validity GHC.Natural.Natural
instance Data.Validity.Validity GHC.Real.Rational
instance Data.Fixed.HasResolution a => Data.Validity.Validity (Data.Fixed.Fixed a)
instance Data.Validity.GValidity GHC.Generics.U1
instance (Data.Validity.GValidity a, Data.Validity.GValidity b) => Data.Validity.GValidity (a GHC.Generics.:*: b)
instance (Data.Validity.GValidity a, Data.Validity.GValidity b) => Data.Validity.GValidity (a GHC.Generics.:+: b)
instance Data.Validity.GValidity a => Data.Validity.GValidity (GHC.Generics.M1 i c a)
instance Data.Validity.Validity a => Data.Validity.GValidity (GHC.Generics.K1 i a)


-- | Relative validity
module Data.RelativeValidity

-- | A class of types that have additional invariants defined upon them
--   that aren't enforced by the type system
--   
--   If there is a <tt>Validity a</tt> instance as well, then <tt>a
--   <a>isValidFor</a> b</tt> should imply <tt>isValid a</tt> for any
--   <tt>b</tt>.
--   
--   If there is a <tt>Validity b</tt> instance as well, then <tt>a
--   <a>isValidFor</a> b</tt> should imply <tt>isValid b</tt> for any
--   <tt>a</tt>.
class RelativeValidity a b
isValidFor :: RelativeValidity a b => a -> b -> Bool
isInvalidFor :: RelativeValidity a b => a -> b -> Bool
