{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Test.Syd.Validity.Functions.Equivalence
    ( equivalentOnGen
    , equivalentOnValid
    , equivalent
    , equivalentOnArbitrary
    , equivalentOnGens2
    , equivalentOnValids2
    , equivalent2
    , equivalentOnArbitrary2
    , equivalentWhenFirstSucceedsOnGen
    , equivalentWhenFirstSucceedsOnValid
    , equivalentWhenFirstSucceeds
    , equivalentWhenFirstSucceedsOnArbitrary
    , equivalentWhenFirstSucceedsOnGens2
    , equivalentWhenFirstSucceedsOnValids2
    , equivalentWhenFirstSucceeds2
    , equivalentWhenFirstSucceedsOnArbitrary2
    , equivalentWhenSecondSucceedsOnGen
    , equivalentWhenSecondSucceedsOnValid
    , equivalentWhenSecondSucceeds
    , equivalentWhenSecondSucceedsOnArbitrary
    , equivalentWhenSecondSucceedsOnGens2
    , equivalentWhenSecondSucceedsOnValids2
    , equivalentWhenSecondSucceeds2
    , equivalentWhenSecondSucceedsOnArbitrary2
    , equivalentWhenSucceedOnGen
    , equivalentWhenSucceedOnValid
    , equivalentWhenSucceed
    , equivalentWhenSucceedOnArbitrary
    , equivalentWhenSucceedOnGens2
    , equivalentWhenSucceedOnValids2
    , equivalentWhenSucceed2
    , equivalentWhenSucceedOnArbitrary2
    , equivalentOnGens3
    , equivalentOnValids3
    , equivalent3
    , equivalentOnArbitrary3
    ) where

import Data.GenValidity

import Test.Syd
import Test.QuickCheck

import Test.Syd.Validity.Types

equivalentOnGen ::
       (Show a, Show b, Eq b)
    => (a -> b)
    -> (a -> b)
    -> Gen a
    -> (a -> [a])
    -> Property
equivalentOnGen :: (a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentOnGen a -> b
f a -> b
g Gen a
gen a -> [a]
s = Gen a -> (a -> [a]) -> (a -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen a
gen a -> [a]
s ((a -> IO ()) -> Property) -> (a -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \a
a -> a -> b
f a
a b -> b -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b
g a
a

equivalentOnValid ::
       (Show a, GenValid a, Show b, Eq b)
    => (a -> b)
    -> (a -> b)
    -> Property
equivalentOnValid :: (a -> b) -> (a -> b) -> Property
equivalentOnValid a -> b
f a -> b
g = (a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
forall a b.
(Show a, Show b, Eq b) =>
(a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentOnGen a -> b
f a -> b
g Gen a
forall a. GenValid a => Gen a
genValid a -> [a]
forall a. GenValid a => a -> [a]
shrinkValid

equivalent ::
       (Show a, GenUnchecked a, Show b, Eq b)
    => (a -> b)
    -> (a -> b)
    -> Property
equivalent :: (a -> b) -> (a -> b) -> Property
equivalent a -> b
f a -> b
g = (a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
forall a b.
(Show a, Show b, Eq b) =>
(a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentOnGen a -> b
f a -> b
g Gen a
forall a. GenUnchecked a => Gen a
genUnchecked a -> [a]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

-- |
--
-- prop> equivalentOnArbitrary ((* 2) . (+ 1)) ((+ 2) . (* 2) :: Int -> Int)
equivalentOnArbitrary ::
       (Show a, Arbitrary a, Show b, Eq b)
    => (a -> b)
    -> (a -> b)
    -> Property
equivalentOnArbitrary :: (a -> b) -> (a -> b) -> Property
equivalentOnArbitrary a -> b
f a -> b
g = (a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
forall a b.
(Show a, Show b, Eq b) =>
(a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentOnGen a -> b
f a -> b
g Gen a
forall a. Arbitrary a => Gen a
arbitrary a -> [a]
forall a. Arbitrary a => a -> [a]
shrink

equivalentOnGens2 ::
       (Show a, Show b, Show c, Eq c)
    => (a -> b -> c)
    -> (a -> b -> c)
    -> Gen (a, b)
    -> ((a, b) -> [(a, b)])
    -> Property
equivalentOnGens2 :: (a -> b -> c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
equivalentOnGens2 a -> b -> c
f a -> b -> c
g Gen (a, b)
gen (a, b) -> [(a, b)]
s =
    Gen (a, b) -> ((a, b) -> [(a, b)]) -> ((a, b) -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen (a, b)
gen (a, b) -> [(a, b)]
s (((a, b) -> IO ()) -> Property) -> ((a, b) -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) -> a -> b -> c
f a
a b
b c -> c -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b -> c
g a
a b
b

equivalentOnValids2 ::
       (Show a, GenValid a, Show b, GenValid b, Show c, Eq c)
    => (a -> b -> c)
    -> (a -> b -> c)
    -> Property
equivalentOnValids2 :: (a -> b -> c) -> (a -> b -> c) -> Property
equivalentOnValids2 a -> b -> c
f a -> b -> c
g = (a -> b -> c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> 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 -> b -> c
f a -> b -> c
g Gen (a, b)
forall a. GenValid a => Gen a
genValid (a, b) -> [(a, b)]
forall a. GenValid a => a -> [a]
shrinkValid

equivalent2 ::
       (Show a, GenUnchecked a, Show b, GenUnchecked b, Show c, Eq c)
    => (a -> b -> c)
    -> (a -> b -> c)
    -> Property
equivalent2 :: (a -> b -> c) -> (a -> b -> c) -> Property
equivalent2 a -> b -> c
f a -> b -> c
g = (a -> b -> c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> 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 -> b -> c
f a -> b -> c
g Gen (a, b)
forall a. GenUnchecked a => Gen a
genUnchecked (a, b) -> [(a, b)]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

-- |
--
-- prop> equivalentOnArbitrary2 (+) ((+) :: Int -> Int -> Int)
equivalentOnArbitrary2 ::
       (Show a, Arbitrary a, Show b, Arbitrary b, Show c, Eq c)
    => (a -> b -> c)
    -> (a -> b -> c)
    -> Property
equivalentOnArbitrary2 :: (a -> b -> c) -> (a -> b -> c) -> Property
equivalentOnArbitrary2 a -> b -> c
f a -> b -> c
g = (a -> b -> c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> 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 -> b -> c
f a -> b -> c
g Gen (a, b)
forall a. Arbitrary a => Gen a
arbitrary (a, b) -> [(a, b)]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenFirstSucceedsOnGen ::
       (Show a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> b)
    -> Gen a
    -> (a -> [a])
    -> Property
equivalentWhenFirstSucceedsOnGen :: (a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenFirstSucceedsOnGen a -> f b
f a -> b
g Gen a
gen a -> [a]
s =
    Gen a -> (a -> [a]) -> (a -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen a
gen a -> [a]
s ((a -> IO ()) -> Property) -> (a -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \a
a ->
        case f b -> Maybe b
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (a -> f b
f a
a) of
            Maybe b
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- fine
            Just b
r -> b
r b -> b -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b
g a
a

equivalentWhenFirstSucceedsOnValid ::
       (Show a, GenValid a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> b)
    -> Property
equivalentWhenFirstSucceedsOnValid :: (a -> f b) -> (a -> b) -> Property
equivalentWhenFirstSucceedsOnValid a -> f b
f a -> b
g =
    (a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenFirstSucceedsOnGen a -> f b
f a -> b
g Gen a
forall a. GenValid a => Gen a
genValid a -> [a]
forall a. GenValid a => a -> [a]
shrinkValid

equivalentWhenFirstSucceedsOnArbitrary ::
       (Show a, Arbitrary a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> b)
    -> Property
equivalentWhenFirstSucceedsOnArbitrary :: (a -> f b) -> (a -> b) -> Property
equivalentWhenFirstSucceedsOnArbitrary a -> f b
f a -> b
g =
    (a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenFirstSucceedsOnGen a -> f b
f a -> b
g Gen a
forall a. Arbitrary a => Gen a
arbitrary a -> [a]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenFirstSucceeds ::
       (Show a, GenUnchecked a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> b)
    -> Property
equivalentWhenFirstSucceeds :: (a -> f b) -> (a -> b) -> Property
equivalentWhenFirstSucceeds a -> f b
f a -> b
g =
    (a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> f b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenFirstSucceedsOnGen a -> f b
f a -> b
g Gen a
forall a. GenUnchecked a => Gen a
genUnchecked a -> [a]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentWhenFirstSucceedsOnGens2 ::
       (Show a, Show b, Show c, Eq c, CanFail f)
    => (a -> b -> f c)
    -> (a -> b -> c)
    -> Gen (a, b)
    -> ((a, b) -> [(a, b)])
    -> Property
equivalentWhenFirstSucceedsOnGens2 :: (a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
equivalentWhenFirstSucceedsOnGens2 a -> b -> f c
f a -> b -> c
g Gen (a, b)
gen (a, b) -> [(a, b)]
s =
    Gen (a, b) -> ((a, b) -> [(a, b)]) -> ((a, b) -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen (a, b)
gen (a, b) -> [(a, b)]
s (((a, b) -> IO ()) -> Property) -> ((a, b) -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) ->
        case f c -> Maybe c
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (a -> b -> f c
f a
a b
b) of
            Maybe c
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- fine
            Just c
rs -> c
rs c -> c -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b -> c
g a
a b
b

equivalentWhenFirstSucceedsOnValids2 ::
       ( Show a
       , GenValid a
       , Show b
       , GenValid b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> f c)
    -> (a -> b -> c)
    -> Property
equivalentWhenFirstSucceedsOnValids2 :: (a -> b -> f c) -> (a -> b -> c) -> Property
equivalentWhenFirstSucceedsOnValids2 a -> b -> f c
f a -> b -> c
g =
    (a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
equivalentWhenFirstSucceedsOnGens2 a -> b -> f c
f a -> b -> c
g Gen (a, b)
forall a. GenValid a => Gen a
genValid (a, b) -> [(a, b)]
forall a. GenValid a => a -> [a]
shrinkValid

equivalentWhenFirstSucceedsOnArbitrary2 ::
       ( Show a
       , Arbitrary a
       , Show b
       , Arbitrary b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> f c)
    -> (a -> b -> c)
    -> Property
equivalentWhenFirstSucceedsOnArbitrary2 :: (a -> b -> f c) -> (a -> b -> c) -> Property
equivalentWhenFirstSucceedsOnArbitrary2 a -> b -> f c
f a -> b -> c
g =
    (a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
equivalentWhenFirstSucceedsOnGens2 a -> b -> f c
f a -> b -> c
g Gen (a, b)
forall a. Arbitrary a => Gen a
arbitrary (a, b) -> [(a, b)]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenFirstSucceeds2 ::
       ( Show a
       , GenUnchecked a
       , Show b
       , GenUnchecked b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> f c)
    -> (a -> b -> c)
    -> Property
equivalentWhenFirstSucceeds2 :: (a -> b -> f c) -> (a -> b -> c) -> Property
equivalentWhenFirstSucceeds2 a -> b -> f c
f a -> b -> c
g =
    (a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> f c)
-> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
equivalentWhenFirstSucceedsOnGens2 a -> b -> f c
f a -> b -> c
g Gen (a, b)
forall a. GenUnchecked a => Gen a
genUnchecked (a, b) -> [(a, b)]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentWhenSecondSucceedsOnGen ::
       (Show a, Show b, Eq b, CanFail f)
    => (a -> b)
    -> (a -> f b)
    -> Gen a
    -> (a -> [a])
    -> Property
equivalentWhenSecondSucceedsOnGen :: (a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSecondSucceedsOnGen a -> b
f a -> f b
g Gen a
gen a -> [a]
s =
    Gen a -> (a -> [a]) -> (a -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen a
gen a -> [a]
s ((a -> IO ()) -> Property) -> (a -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \a
a ->
        case f b -> Maybe b
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (a -> f b
g a
a) of
            Maybe b
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- fine
            Just b
r -> b
r b -> b -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b
f a
a

equivalentWhenSecondSucceedsOnValid ::
       (Show a, GenValid a, Show b, Eq b, CanFail f)
    => (a -> b)
    -> (a -> f b)
    -> Property
equivalentWhenSecondSucceedsOnValid :: (a -> b) -> (a -> f b) -> Property
equivalentWhenSecondSucceedsOnValid a -> b
f a -> f b
g =
    (a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSecondSucceedsOnGen a -> b
f a -> f b
g Gen a
forall a. GenValid a => Gen a
genValid a -> [a]
forall a. GenValid a => a -> [a]
shrinkValid

equivalentWhenSecondSucceedsOnArbitrary ::
       (Show a, Arbitrary a, Show b, Eq b, CanFail f)
    => (a -> b)
    -> (a -> f b)
    -> Property
equivalentWhenSecondSucceedsOnArbitrary :: (a -> b) -> (a -> f b) -> Property
equivalentWhenSecondSucceedsOnArbitrary a -> b
f a -> f b
g =
    (a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSecondSucceedsOnGen a -> b
f a -> f b
g Gen a
forall a. Arbitrary a => Gen a
arbitrary a -> [a]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenSecondSucceeds ::
       (Show a, GenUnchecked a, Show b, Eq b, CanFail f)
    => (a -> b)
    -> (a -> f b)
    -> Property
equivalentWhenSecondSucceeds :: (a -> b) -> (a -> f b) -> Property
equivalentWhenSecondSucceeds a -> b
f a -> f b
g =
    (a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSecondSucceedsOnGen a -> b
f a -> f b
g Gen a
forall a. GenUnchecked a => Gen a
genUnchecked a -> [a]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentWhenSecondSucceedsOnGens2 ::
       (Show a, Show b, Show c, Eq c, CanFail f)
    => (a -> b -> c)
    -> (a -> b -> f c)
    -> Gen (a, b)
    -> ((a, b) -> [(a, b)])
    -> Property
equivalentWhenSecondSucceedsOnGens2 :: (a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSecondSucceedsOnGens2 a -> b -> c
f a -> b -> f c
g Gen (a, b)
gen (a, b) -> [(a, b)]
s =
    Gen (a, b) -> ((a, b) -> [(a, b)]) -> ((a, b) -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen (a, b)
gen (a, b) -> [(a, b)]
s (((a, b) -> IO ()) -> Property) -> ((a, b) -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) ->
        case f c -> Maybe c
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (a -> b -> f c
g a
a b
b) of
            Maybe c
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- fine
            Just c
rs -> c
rs c -> c -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b -> c
f a
a b
b

equivalentWhenSecondSucceedsOnValids2 ::
       ( Show a
       , GenValid a
       , Show b
       , GenValid b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> c)
    -> (a -> b -> f c)
    -> Property
equivalentWhenSecondSucceedsOnValids2 :: (a -> b -> c) -> (a -> b -> f c) -> Property
equivalentWhenSecondSucceedsOnValids2 a -> b -> c
f a -> b -> f c
g =
    (a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSecondSucceedsOnGens2 a -> b -> c
f a -> b -> f c
g Gen (a, b)
forall a. GenValid a => Gen a
genValid (a, b) -> [(a, b)]
forall a. GenValid a => a -> [a]
shrinkValid

equivalentWhenSecondSucceedsOnArbitrary2 ::
       ( Show a
       , Arbitrary a
       , Show b
       , Arbitrary b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> c)
    -> (a -> b -> f c)
    -> Property
equivalentWhenSecondSucceedsOnArbitrary2 :: (a -> b -> c) -> (a -> b -> f c) -> Property
equivalentWhenSecondSucceedsOnArbitrary2 a -> b -> c
f a -> b -> f c
g =
    (a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSecondSucceedsOnGens2 a -> b -> c
f a -> b -> f c
g Gen (a, b)
forall a. Arbitrary a => Gen a
arbitrary (a, b) -> [(a, b)]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenSecondSucceeds2 ::
       ( Show a
       , GenUnchecked a
       , Show b
       , GenUnchecked b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> c)
    -> (a -> b -> f c)
    -> Property
equivalentWhenSecondSucceeds2 :: (a -> b -> c) -> (a -> b -> f c) -> Property
equivalentWhenSecondSucceeds2 a -> b -> c
f a -> b -> f c
g =
    (a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSecondSucceedsOnGens2 a -> b -> c
f a -> b -> f c
g Gen (a, b)
forall a. GenUnchecked a => Gen a
genUnchecked (a, b) -> [(a, b)]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentWhenSucceedOnGen ::
       (Show a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> f b)
    -> Gen a
    -> (a -> [a])
    -> Property
equivalentWhenSucceedOnGen :: (a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSucceedOnGen a -> f b
f a -> f b
g Gen a
gen a -> [a]
s =
    Gen a -> (a -> [a]) -> (a -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen a
gen a -> [a]
s ((a -> IO ()) -> Property) -> (a -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \a
a ->
        case do b
fa <- f b -> Maybe b
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (f b -> Maybe b) -> f b -> Maybe b
forall a b. (a -> b) -> a -> b
$ a -> f b
f a
a
                b
ga <- f b -> Maybe b
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (f b -> Maybe b) -> f b -> Maybe b
forall a b. (a -> b) -> a -> b
$ a -> f b
g a
a
                (b, b) -> Maybe (b, b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b
fa, b
ga) of
            Maybe (b, b)
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- fine
            Just (b
fa, b
ga) -> b
fa b -> b -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` b
ga

equivalentWhenSucceedOnValid ::
       (Show a, GenValid a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> f b)
    -> Property
equivalentWhenSucceedOnValid :: (a -> f b) -> (a -> f b) -> Property
equivalentWhenSucceedOnValid a -> f b
f a -> f b
g =
    (a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSucceedOnGen a -> f b
f a -> f b
g Gen a
forall a. GenValid a => Gen a
genValid a -> [a]
forall a. GenValid a => a -> [a]
shrinkValid

equivalentWhenSucceed ::
       (Show a, GenUnchecked a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> f b)
    -> Property
equivalentWhenSucceed :: (a -> f b) -> (a -> f b) -> Property
equivalentWhenSucceed a -> f b
f a -> f b
g =
    (a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSucceedOnGen a -> f b
f a -> f b
g Gen a
forall a. GenUnchecked a => Gen a
genUnchecked a -> [a]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentWhenSucceedOnArbitrary ::
       (Show a, Arbitrary a, Show b, Eq b, CanFail f)
    => (a -> f b)
    -> (a -> f b)
    -> Property
equivalentWhenSucceedOnArbitrary :: (a -> f b) -> (a -> f b) -> Property
equivalentWhenSucceedOnArbitrary a -> f b
f a -> f b
g =
    (a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
forall a b (f :: * -> *).
(Show a, Show b, Eq b, CanFail f) =>
(a -> f b) -> (a -> f b) -> Gen a -> (a -> [a]) -> Property
equivalentWhenSucceedOnGen a -> f b
f a -> f b
g Gen a
forall a. Arbitrary a => Gen a
arbitrary a -> [a]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenSucceedOnGens2 ::
       (Show a, Show b, Show c, Eq c, CanFail f)
    => (a -> b -> f c)
    -> (a -> b -> f c)
    -> Gen (a, b)
    -> ((a, b) -> [(a, b)])
    -> Property
equivalentWhenSucceedOnGens2 :: (a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSucceedOnGens2 a -> b -> f c
f a -> b -> f c
g Gen (a, b)
gen (a, b) -> [(a, b)]
s =
    Gen (a, b) -> ((a, b) -> [(a, b)]) -> ((a, b) -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen (a, b)
gen (a, b) -> [(a, b)]
s (((a, b) -> IO ()) -> Property) -> ((a, b) -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b) ->
        case do c
fab <- f c -> Maybe c
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (f c -> Maybe c) -> f c -> Maybe c
forall a b. (a -> b) -> a -> b
$ a -> b -> f c
f a
a b
b
                c
gab <- f c -> Maybe c
forall (f :: * -> *) a. CanFail f => f a -> Maybe a
resultIfSucceeded (f c -> Maybe c) -> f c -> Maybe c
forall a b. (a -> b) -> a -> b
$ a -> b -> f c
g a
a b
b
                (c, c) -> Maybe (c, c)
forall (m :: * -> *) a. Monad m => a -> m a
return (c
fab, c
gab) of
            Maybe (c, c)
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return () -- fine
            Just (c
fab, c
gab) -> c
fab c -> c -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` c
gab

equivalentWhenSucceedOnValids2 ::
       ( Show a
       , GenValid a
       , Show b
       , GenValid b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> f c)
    -> (a -> b -> f c)
    -> Property
equivalentWhenSucceedOnValids2 :: (a -> b -> f c) -> (a -> b -> f c) -> Property
equivalentWhenSucceedOnValids2 a -> b -> f c
f a -> b -> f c
g =
    (a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSucceedOnGens2 a -> b -> f c
f a -> b -> f c
g Gen (a, b)
forall a. GenValid a => Gen a
genValid (a, b) -> [(a, b)]
forall a. GenValid a => a -> [a]
shrinkValid

equivalentWhenSucceedOnArbitrary2 ::
       ( Show a
       , Arbitrary a
       , Show b
       , Arbitrary b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> f c)
    -> (a -> b -> f c)
    -> Property
equivalentWhenSucceedOnArbitrary2 :: (a -> b -> f c) -> (a -> b -> f c) -> Property
equivalentWhenSucceedOnArbitrary2 a -> b -> f c
f a -> b -> f c
g =
    (a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSucceedOnGens2 a -> b -> f c
f a -> b -> f c
g Gen (a, b)
forall a. Arbitrary a => Gen a
arbitrary (a, b) -> [(a, b)]
forall a. Arbitrary a => a -> [a]
shrink

equivalentWhenSucceed2 ::
       ( Show a
       , GenUnchecked a
       , Show b
       , GenUnchecked b
       , Show c
       , Eq c
       , CanFail f
       )
    => (a -> b -> f c)
    -> (a -> b -> f c)
    -> Property
equivalentWhenSucceed2 :: (a -> b -> f c) -> (a -> b -> f c) -> Property
equivalentWhenSucceed2 a -> b -> f c
f a -> b -> f c
g =
    (a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
forall a b c (f :: * -> *).
(Show a, Show b, Show c, Eq c, CanFail f) =>
(a -> b -> f c)
-> (a -> b -> f c)
-> Gen (a, b)
-> ((a, b) -> [(a, b)])
-> Property
equivalentWhenSucceedOnGens2 a -> b -> f c
f a -> b -> f c
g Gen (a, b)
forall a. GenUnchecked a => Gen a
genUnchecked (a, b) -> [(a, b)]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentOnGens3 ::
       (Show a, Show b, Show c, Show d, Eq d)
    => (a -> b -> c -> d)
    -> (a -> b -> c -> d)
    -> Gen (a, b, c)
    -> ((a, b, c) -> [(a, b, c)])
    -> Property
equivalentOnGens3 :: (a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
equivalentOnGens3 a -> b -> c -> d
f a -> b -> c -> d
g Gen (a, b, c)
gen (a, b, c) -> [(a, b, c)]
s =
    Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)]) -> ((a, b, c) -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen (a, b, c)
gen (a, b, c) -> [(a, b, c)]
s (((a, b, c) -> IO ()) -> Property)
-> ((a, b, c) -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \(a
a, b
b, c
c) -> a -> b -> c -> d
f a
a b
b c
c d -> d -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` a -> b -> c -> d
g a
a b
b c
c

equivalentOnValids3 ::
       ( Show a
       , GenValid a
       , Show b
       , GenValid b
       , Show c
       , GenValid c
       , Show d
       , Eq d
       )
    => (a -> b -> c -> d)
    -> (a -> b -> c -> d)
    -> Property
equivalentOnValids3 :: (a -> b -> c -> d) -> (a -> b -> c -> d) -> Property
equivalentOnValids3 a -> b -> c -> d
f a -> b -> c -> d
g = (a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
forall a b c d.
(Show a, Show b, Show c, Show d, Eq d) =>
(a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
equivalentOnGens3 a -> b -> c -> d
f a -> b -> c -> d
g Gen (a, b, c)
forall a. GenValid a => Gen a
genValid (a, b, c) -> [(a, b, c)]
forall a. GenValid a => a -> [a]
shrinkValid

equivalent3 ::
       ( Show a
       , GenUnchecked a
       , Show b
       , GenUnchecked b
       , Show c
       , GenUnchecked c
       , Show d
       , Eq d
       )
    => (a -> b -> c -> d)
    -> (a -> b -> c -> d)
    -> Property
equivalent3 :: (a -> b -> c -> d) -> (a -> b -> c -> d) -> Property
equivalent3 a -> b -> c -> d
f a -> b -> c -> d
g = (a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
forall a b c d.
(Show a, Show b, Show c, Show d, Eq d) =>
(a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
equivalentOnGens3 a -> b -> c -> d
f a -> b -> c -> d
g Gen (a, b, c)
forall a. GenUnchecked a => Gen a
genUnchecked (a, b, c) -> [(a, b, c)]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

equivalentOnArbitrary3 ::
       ( Show a
       , Arbitrary a
       , Show b
       , Arbitrary b
       , Show c
       , Arbitrary c
       , Show d
       , Eq d
       )
    => (a -> b -> c -> d)
    -> (a -> b -> c -> d)
    -> Property
equivalentOnArbitrary3 :: (a -> b -> c -> d) -> (a -> b -> c -> d) -> Property
equivalentOnArbitrary3 a -> b -> c -> d
f a -> b -> c -> d
g = (a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
forall a b c d.
(Show a, Show b, Show c, Show d, Eq d) =>
(a -> b -> c -> d)
-> (a -> b -> c -> d)
-> Gen (a, b, c)
-> ((a, b, c) -> [(a, b, c)])
-> Property
equivalentOnGens3 a -> b -> c -> d
f a -> b -> c -> d
g Gen (a, b, c)
forall a. Arbitrary a => Gen a
arbitrary (a, b, c) -> [(a, b, c)]
forall a. Arbitrary a => a -> [a]
shrink