    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE TypeApplications #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE AllowAmbiguousTypes #-}

    -- | Ord properties
    --
    -- You will need @TypeApplications@ to use these.
    module Test.Validity.Ord
        ( ordSpecOnGen
        , ordSpecOnValid
        , ordSpecOnInvalid
        , ordSpec
        , ordSpecOnArbitrary
        ) where

    import Data.Data

    import Data.GenValidity

    import Test.Hspec
    import Test.QuickCheck

    import Test.Validity.Functions
    import Test.Validity.Relations
    import Test.Validity.Utils

    {-# ANN module "HLint: ignore Use <=" #-}

    {-# ANN module "HLint: ignore Use >=" #-}

    {-# ANN module "HLint: ignore Use <" #-}

    {-# ANN module "HLint: ignore Use >" #-}

    leTypeStr ::
           forall a. Typeable a
        => String
    leTypeStr :: String
    leTypeStr = String -> String
    forall k (a :: k). Typeable a => String -> String
    binRelStr @a "<="

    geTypeStr ::
           forall a. Typeable a
        => String
    geTypeStr :: String
    geTypeStr = String -> String
    forall k (a :: k). Typeable a => String -> String
    binRelStr @a ">="

    ltTypeStr ::
           forall a. Typeable a
        => String
    ltTypeStr :: String
    ltTypeStr = String -> String
    forall k (a :: k). Typeable a => String -> String
    binRelStr @a "<"

    gtTypeStr ::
           forall a. Typeable a
        => String
    gtTypeStr :: String
    gtTypeStr = String -> String
    forall k (a :: k). Typeable a => String -> String
    binRelStr @a ">"

    -- | Standard test spec for properties of Ord instances for valid values
    --
    -- Example usage:
    --
    -- > ordSpecOnValid @Double
    ordSpecOnValid ::
           forall a. (Show a, Ord a, Typeable a, GenValid a)
        => Spec
    ordSpecOnValid :: Spec
    ordSpecOnValid = Gen a -> String -> (a -> [a]) -> Spec
    forall a.
    (Show a, Eq a, Ord a, Typeable a) =>
    Gen a -> String -> (a -> [a]) -> Spec
    ordSpecOnGen @a Gen a
    forall a. GenValid a => Gen a
    genValid "valid" a -> [a]
    forall a. GenValid a => a -> [a]
    shrinkValid

    -- | Standard test spec for properties of Ord instances for invalid values
    --
    -- Example usage:
    --
    -- > ordSpecOnInvalid @Double
    ordSpecOnInvalid ::
           forall a. (Show a, Ord a, Typeable a, GenInvalid a)
        => Spec
    ordSpecOnInvalid :: Spec
    ordSpecOnInvalid = Gen a -> String -> (a -> [a]) -> Spec
    forall a.
    (Show a, Eq a, Ord a, Typeable a) =>
    Gen a -> String -> (a -> [a]) -> Spec
    ordSpecOnGen @a Gen a
    forall a. GenInvalid a => Gen a
    genInvalid "invalid" a -> [a]
    forall a. GenInvalid a => a -> [a]
    shrinkInvalid

    -- | Standard test spec for properties of Ord instances for unchecked values
    --
    -- Example usage:
    --
    -- > ordSpec @Int
    ordSpec ::
           forall a. (Show a, Ord a, Typeable a, GenUnchecked a)
        => Spec
    ordSpec :: Spec
    ordSpec = Gen a -> String -> (a -> [a]) -> Spec
    forall a.
    (Show a, Eq a, Ord a, Typeable a) =>
    Gen a -> String -> (a -> [a]) -> Spec
    ordSpecOnGen @a Gen a
    forall a. GenUnchecked a => Gen a
    genUnchecked "unchecked" a -> [a]
    forall a. GenUnchecked a => a -> [a]
    shrinkUnchecked

    -- | Standard test spec for properties of Ord instances for arbitrary values
    --
    -- Example usage:
    --
    -- > ordSpecOnArbitrary @Int
    ordSpecOnArbitrary ::
           forall a. (Show a, Ord a, Typeable a, Arbitrary a)
        => Spec
    ordSpecOnArbitrary :: Spec
    ordSpecOnArbitrary = Gen a -> String -> (a -> [a]) -> Spec
    forall a.
    (Show a, Eq a, Ord a, Typeable a) =>
    Gen a -> String -> (a -> [a]) -> Spec
    ordSpecOnGen @a Gen a
    forall a. Arbitrary a => Gen a
    arbitrary "arbitrary" a -> [a]
    forall a. Arbitrary a => a -> [a]
    shrink

    -- | Standard test spec for properties of Ord instances for values generated by a given generator (and name for that generator).
    --
    -- Example usage:
    --
    -- > ordSpecOnGen ((* 2) <$> genValid @Int) "even"
    ordSpecOnGen ::
           forall a. (Show a, Eq a, Ord a, Typeable a)
        => Gen a
        -> String
        -> (a -> [a])
        -> Spec
    ordSpecOnGen :: Gen a -> String -> (a -> [a]) -> Spec
    ordSpecOnGen gen :: Gen a
    gen genname :: String
    genname s :: a -> [a]
    s =
        Spec -> Spec
    forall a. SpecWith a -> SpecWith a
    parallel (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
            let name :: String
    name = Typeable a => String
    forall k (a :: k). Typeable a => String
    nameOf @a
                funlestr :: String
    funlestr = Typeable a => String
    forall a. Typeable a => String
    leTypeStr @a
                fungestr :: String
    fungestr = Typeable a => String
    forall a. Typeable a => String
    geTypeStr @a
                funltstr :: String
    funltstr = Typeable a => String
    forall a. Typeable a => String
    ltTypeStr @a
                fungtstr :: String
    fungtstr = Typeable a => String
    forall a. Typeable a => String
    gtTypeStr @a
                minmaxtstr :: String -> String
    minmaxtstr = Typeable (a -> a -> a) => String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(a->a->a)
                itProp :: String -> a -> SpecWith (Arg a)
    itProp s_ :: String
    s_ = String -> a -> SpecWith (Arg a)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it (String -> a -> SpecWith (Arg a))
    -> String -> a -> SpecWith (Arg a)
    forall a b. (a -> b) -> a -> b
    $ [String] -> String
    unwords
                    [ String
    s_
                      , "\"" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    genname
                      , String
    name String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "\"" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "'s"
                    ]
                cmple :: a -> a -> Bool
    cmple = Ord a => a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    (<=) @a
                cmpge :: a -> a -> Bool
    cmpge = Ord a => a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    (>=) @a
                cmplt :: a -> a -> Bool
    cmplt = Ord a => a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    (<) @a
                cmpgt :: a -> a -> Bool
    cmpgt = Ord a => a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    (>) @a
                gen2 :: Gen (a, a)
    gen2 = (,) (a -> a -> (a, a)) -> Gen a -> Gen (a -> (a, a))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen a
    gen Gen (a -> (a, a)) -> Gen a -> Gen (a, a)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Gen a
    gen
                gen3 :: Gen (a, a, a)
    gen3 = (,,) (a -> a -> a -> (a, a, a)) -> Gen a -> Gen (a -> a -> (a, a, a))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen a
    gen Gen (a -> a -> (a, a, a)) -> Gen a -> Gen (a -> (a, a, a))
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Gen a
    gen Gen (a -> (a, a, a)) -> Gen a -> Gen (a, a, a)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Gen a
    gen
                s2 :: (a, a) -> [(a, a)]
    s2 = (a -> [a]) -> (a, a) -> [(a, a)]
    forall a. (a -> [a]) -> (a, a) -> [(a, a)]
    shrinkT2 a -> [a]
    s
            String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe ("Ord " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    name) (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe String
    funlestr (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is reflexive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    reflexivityOnGen a -> a -> Bool
    cmple Gen a
    gen a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is antisymmetric for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen (a, a) -> (a -> [a]) -> Property
    forall a.
    (Show a, Eq a) =>
    (a -> a -> Bool) -> Gen (a, a) -> (a -> [a]) -> Property
    antisymmetryOnGens a -> a -> Bool
    cmple Gen (a, a)
    gen2 a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is transitive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    transitivityOnGens a -> a -> Bool
    cmple Gen (a, a, a)
    gen3 a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is equivalent to (\\a b -> compare a b /= GT) for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> Gen (a, a)
    -> ((a, a) -> [(a, a)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 a -> a -> Bool
    cmple (\a :: a
    a b :: a
    b -> a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    a a
    b Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Ordering
    GT) Gen (a, a)
    gen2 (a, a) -> [(a, a)]
    s2
                String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe String
    fungestr (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is reflexive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    reflexivityOnGen a -> a -> Bool
    cmpge Gen a
    gen a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is antisymmetric for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen (a, a) -> (a -> [a]) -> Property
    forall a.
    (Show a, Eq a) =>
    (a -> a -> Bool) -> Gen (a, a) -> (a -> [a]) -> Property
    antisymmetryOnGens a -> a -> Bool
    cmpge Gen (a, a)
    gen2 a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is transitive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    transitivityOnGens a -> a -> Bool
    cmpge Gen (a, a, a)
    gen3 a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is equivalent to (\\a b -> compare a b /= LT) for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> Gen (a, a)
    -> ((a, a) -> [(a, a)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 a -> a -> Bool
    cmpge (\a :: a
    a b :: a
    b -> a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    a a
    b Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Ordering
    LT) Gen (a, a)
    gen2 (a, a) -> [(a, a)]
    s2
                String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe String
    funltstr (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is antireflexive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    antireflexivityOnGen a -> a -> Bool
    cmplt Gen a
    gen a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is transitive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    transitivityOnGens a -> a -> Bool
    cmplt Gen (a, a, a)
    gen3 a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is equivalent to (\\a b -> compare a b == LT) for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> Gen (a, a)
    -> ((a, a) -> [(a, a)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 a -> a -> Bool
    cmplt (\a :: a
    a b :: a
    b -> a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    a a
    b Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    LT) Gen (a, a)
    gen2 (a, a) -> [(a, a)]
    s2
                String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe String
    fungtstr (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is antireflexive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen a -> (a -> [a]) -> Property
    antireflexivityOnGen a -> a -> Bool
    cmpgt Gen a
    gen a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is transitive for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    forall a.
    Show a =>
    (a -> a -> Bool) -> Gen (a, a, a) -> (a -> [a]) -> Property
    transitivityOnGens a -> a -> Bool
    cmpgt Gen (a, a, a)
    gen3 a -> [a]
    s
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is equivalent to (\\a b -> compare a b == GT) for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> Gen (a, a)
    -> ((a, a) -> [(a, a)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 a -> a -> Bool
    cmpgt (\a :: a
    a b :: a
    b -> a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    a a
    b Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    GT) Gen (a, a)
    gen2 (a, a) -> [(a, a)]
    s2
                String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe (String -> String
    minmaxtstr "min") (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is equivalent to (\\a b -> if a <= b then a else b) for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> a)
    -> (a -> a -> a) -> Gen (a, a) -> ((a, a) -> [(a, a)]) -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 a -> a -> a
    forall a. Ord a => a -> a -> a
    min (\a :: a
    a b :: a
    b -> if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    b then a
    a else a
    b) Gen (a, a)
    gen2 (a, a) -> [(a, a)]
    s2
                String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe (String -> String
    minmaxtstr "max") (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                    String -> Property -> SpecWith (Arg Property)
    forall a. Example a => String -> a -> SpecWith (Arg a)
    itProp "is equivalent to (\\a b -> if a >= b then a else b) for" (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                        (a -> a -> a)
    -> (a -> a -> a) -> Gen (a, a) -> ((a, a) -> [(a, a)]) -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 a -> a -> a
    forall a. Ord a => a -> a -> a
    max (\a :: a
    a b :: a
    b -> if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    >= a
    b then a
    a else a
    b) Gen (a, a)
    gen2 (a, a) -> [(a, a)]
    s2