    {-# LANGUAGE CPP #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    #if HAVE_QUANTIFIED_CONSTRAINTS
    {-# LANGUAGE QuantifiedConstraints #-}
    #endif

    {-# OPTIONS_GHC -Wall #-}

    module Test.QuickCheck.Classes.Bitraversable
      (
    #if HAVE_BINARY_LAWS
        bitraversableLaws
    #endif
      ) where

    import Data.Bitraversable(Bitraversable(..))
    import Test.QuickCheck hiding ((.&.))
    #if HAVE_BINARY_LAWS
    import Data.Functor.Compose (Compose(..))
    import Data.Functor.Identity (Identity(..))
    import Data.Functor.Classes (Eq2,Show2)
    #endif
    import Test.QuickCheck.Property (Property)

    import Test.QuickCheck.Classes.Internal

    #if HAVE_BINARY_LAWS

    -- | Tests the following 'Bitraversable' properties:
    --
    -- [/Naturality/]
    --   @'bitraverse' (t '.' f) (t '.' g) ≡ t '.' 'bitraverse' f g@ for every applicative transformation @t@
    -- [/Identity/]
    --   @'bitraverse' 'Identity' 'Identity' ≡ 'Identity'@
    -- [/Composition/]
    --   @'Compose' '.' 'fmap' ('bitraverse' g1 g2) '.' 'bitraverse' f1 f2 ≡ 'bitraverse' ('Compose' '.' 'fmap' g1 g2 '.' f1) ('Compose' '.' 'fmap' g2 '.' f2)@
    --
    -- /Note/: This property test is only available when this package is built with
    -- @base-4.9+@ or @transformers-0.5+@.
    bitraversableLaws :: forall proxy f.
    #if HAVE_QUANTIFIED_CONSTRAINTS
      (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
    #else
      (Bitraversable f, Eq2 f, Show2 f, Arbitrary2 f)
    #endif
      => proxy f -> Laws
    bitraversableLaws :: forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Laws
    bitraversableLaws proxy f
    p = String -> [(String, Property)] -> Laws
    Laws String
    "Bitraversable"
      [ (String
    "Naturality", proxy f -> Property
    forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Property
    bitraversableNaturality proxy f
    p)
      , (String
    "Identity", proxy f -> Property
    forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Property
    bitraversableIdentity proxy f
    p)
      , (String
    "Composition", proxy f -> Property
    forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Property
    bitraversableComposition proxy f
    p)
      ]

    bitraversableNaturality :: forall proxy f.
    #if HAVE_QUANTIFIED_CONSTRAINTS
      (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
    #else
      (Bitraversable f, Eq2 f, Show2 f, Arbitrary2 f)
    #endif
      => proxy f -> Property
    bitraversableNaturality :: forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Property
    bitraversableNaturality proxy f
    _ = (Apply2 f Integer Integer -> Bool) -> Property
    forall prop. Testable prop => prop -> Property
    property ((Apply2 f Integer Integer -> Bool) -> Property)
    -> (Apply2 f Integer Integer -> Bool) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(Apply2 (f Integer Integer
    x :: f Integer Integer)) ->
      let t :: Compose Triple (Writer (Set Integer)) a
    -> Compose (Writer (Set Integer)) Triple a
    t = Compose Triple (Writer (Set Integer)) a
    -> Compose (Writer (Set Integer)) Triple a
    forall a.
    Compose Triple (Writer (Set Integer)) a
    -> Compose (Writer (Set Integer)) Triple a
    apTrans
          f :: Integer -> Compose Triple (Writer (Set Integer)) Integer
    f = Integer -> Compose Triple (Writer (Set Integer)) Integer
    func4
          g :: Integer -> Compose Triple (Writer (Set Integer)) Integer
    g = Integer -> Compose Triple (Writer (Set Integer)) Integer
    func4
          x' :: Compose (Writer (Set Integer)) Triple (f Integer Integer)
    x' = (Integer -> Compose (Writer (Set Integer)) Triple Integer)
    -> (Integer -> Compose (Writer (Set Integer)) Triple Integer)
    -> f Integer Integer
    -> Compose (Writer (Set Integer)) Triple (f Integer Integer)
    forall (f :: * -> *) a c b d.
    Applicative f =>
    (a -> f c) -> (b -> f d) -> f a b -> f (f c d)
    forall (t :: * -> * -> *) (f :: * -> *) a c b d.
    (Bitraversable t, Applicative f) =>
    (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
    bitraverse (Compose Triple (Writer (Set Integer)) Integer
    -> Compose (Writer (Set Integer)) Triple Integer
    forall a.
    Compose Triple (Writer (Set Integer)) a
    -> Compose (Writer (Set Integer)) Triple a
    t (Compose Triple (Writer (Set Integer)) Integer
     -> Compose (Writer (Set Integer)) Triple Integer)
    -> (Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> Integer
    -> Compose (Writer (Set Integer)) Triple Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Compose Triple (Writer (Set Integer)) Integer
    f) (Compose Triple (Writer (Set Integer)) Integer
    -> Compose (Writer (Set Integer)) Triple Integer
    forall a.
    Compose Triple (Writer (Set Integer)) a
    -> Compose (Writer (Set Integer)) Triple a
    t (Compose Triple (Writer (Set Integer)) Integer
     -> Compose (Writer (Set Integer)) Triple Integer)
    -> (Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> Integer
    -> Compose (Writer (Set Integer)) Triple Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Compose Triple (Writer (Set Integer)) Integer
    g) f Integer Integer
    x
          y' :: Compose (Writer (Set Integer)) Triple (f Integer Integer)
    y' = Compose Triple (Writer (Set Integer)) (f Integer Integer)
    -> Compose (Writer (Set Integer)) Triple (f Integer Integer)
    forall a.
    Compose Triple (Writer (Set Integer)) a
    -> Compose (Writer (Set Integer)) Triple a
    t ((Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> (Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> f Integer Integer
    -> Compose Triple (Writer (Set Integer)) (f Integer Integer)
    forall (f :: * -> *) a c b d.
    Applicative f =>
    (a -> f c) -> (b -> f d) -> f a b -> f (f c d)
    forall (t :: * -> * -> *) (f :: * -> *) a c b d.
    (Bitraversable t, Applicative f) =>
    (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
    bitraverse Integer -> Compose Triple (Writer (Set Integer)) Integer
    f Integer -> Compose Triple (Writer (Set Integer)) Integer
    g f Integer Integer
    x)
      in Compose (Writer (Set Integer)) Triple (f Integer Integer)
    -> Compose (Writer (Set Integer)) Triple (f Integer Integer)
    -> Bool
    forall (f :: * -> *) (g :: * -> * -> *) x y.
    (forall a. Eq a => Eq (f a),
     forall a b. (Eq a, Eq b) => Eq (g a b), Eq x, Eq y) =>
    f (g x y) -> f (g x y) -> Bool
    eq1_2 Compose (Writer (Set Integer)) Triple (f Integer Integer)
    x' Compose (Writer (Set Integer)) Triple (f Integer Integer)
    y'

    bitraversableIdentity :: forall proxy f.
    #if HAVE_QUANTIFIED_CONSTRAINTS
      (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
    #else
      (Bitraversable f, Eq2 f, Show2 f, Arbitrary2 f)
    #endif
      => proxy f -> Property
    bitraversableIdentity :: forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Property
    bitraversableIdentity proxy f
    _ = (Apply2 f Integer Integer -> Bool) -> Property
    forall prop. Testable prop => prop -> Property
    property ((Apply2 f Integer Integer -> Bool) -> Property)
    -> (Apply2 f Integer Integer -> Bool) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(Apply2 (f Integer Integer
    x :: f Integer Integer)) -> Identity (f Integer Integer)
    -> Identity (f Integer Integer) -> Bool
    forall (f :: * -> *) (g :: * -> * -> *) x y.
    (forall a. Eq a => Eq (f a),
     forall a b. (Eq a, Eq b) => Eq (g a b), Eq x, Eq y) =>
    f (g x y) -> f (g x y) -> Bool
    eq1_2 ((Integer -> Identity Integer)
    -> (Integer -> Identity Integer)
    -> f Integer Integer
    -> Identity (f Integer Integer)
    forall (f :: * -> *) a c b d.
    Applicative f =>
    (a -> f c) -> (b -> f d) -> f a b -> f (f c d)
    forall (t :: * -> * -> *) (f :: * -> *) a c b d.
    (Bitraversable t, Applicative f) =>
    (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
    bitraverse Integer -> Identity Integer
    forall a. a -> Identity a
    Identity Integer -> Identity Integer
    forall a. a -> Identity a
    Identity f Integer Integer
    x) (f Integer Integer -> Identity (f Integer Integer)
    forall a. a -> Identity a
    Identity f Integer Integer
    x)

    bitraversableComposition :: forall proxy f.
    #if HAVE_QUANTIFIED_CONSTRAINTS
      (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
    #else
      (Bitraversable f, Eq2 f, Show2 f, Arbitrary2 f)
    #endif
      => proxy f -> Property
    bitraversableComposition :: forall (proxy :: (* -> * -> *) -> *) (f :: * -> * -> *).
    (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b),
     forall a b. (Show a, Show b) => Show (f a b),
     forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b)) =>
    proxy f -> Property
    bitraversableComposition proxy f
    _ = (Apply2 f Integer Integer -> Bool) -> Property
    forall prop. Testable prop => prop -> Property
    property ((Apply2 f Integer Integer -> Bool) -> Property)
    -> (Apply2 f Integer Integer -> Bool) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(Apply2 (f Integer Integer
    x :: f Integer Integer)) ->
      let f1 :: Integer -> Triple Integer
    f1 = Integer -> Triple Integer
    func6
          f2 :: Integer -> Triple Integer
    f2 = Integer -> Triple Integer
    func5
          g1 :: Integer -> Compose Triple (Writer (Set Integer)) Integer
    g1 = Integer -> Compose Triple (Writer (Set Integer)) Integer
    func4
          g2 :: Integer -> Compose Triple (Writer (Set Integer)) Integer
    g2 = Integer -> Compose Triple (Writer (Set Integer)) Integer
    func4
          x' :: Compose
      Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    x' = Triple (Compose Triple (Writer (Set Integer)) (f Integer Integer))
    -> Compose
         Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
    f (g a) -> Compose f g a
    Compose (Triple (Compose Triple (Writer (Set Integer)) (f Integer Integer))
     -> Compose
          Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer))
    -> (f Integer Integer
        -> Triple
             (Compose Triple (Writer (Set Integer)) (f Integer Integer)))
    -> f Integer Integer
    -> Compose
         Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (f Integer Integer
     -> Compose Triple (Writer (Set Integer)) (f Integer Integer))
    -> Triple (f Integer Integer)
    -> Triple
         (Compose Triple (Writer (Set Integer)) (f Integer Integer))
    forall a b. (a -> b) -> Triple a -> Triple b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> (Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> f Integer Integer
    -> Compose Triple (Writer (Set Integer)) (f Integer Integer)
    forall (f :: * -> *) a c b d.
    Applicative f =>
    (a -> f c) -> (b -> f d) -> f a b -> f (f c d)
    forall (t :: * -> * -> *) (f :: * -> *) a c b d.
    (Bitraversable t, Applicative f) =>
    (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
    bitraverse Integer -> Compose Triple (Writer (Set Integer)) Integer
    g1 Integer -> Compose Triple (Writer (Set Integer)) Integer
    g2) (Triple (f Integer Integer)
     -> Triple
          (Compose Triple (Writer (Set Integer)) (f Integer Integer)))
    -> (f Integer Integer -> Triple (f Integer Integer))
    -> f Integer Integer
    -> Triple
         (Compose Triple (Writer (Set Integer)) (f Integer Integer))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Integer -> Triple Integer)
    -> (Integer -> Triple Integer)
    -> f Integer Integer
    -> Triple (f Integer Integer)
    forall (f :: * -> *) a c b d.
    Applicative f =>
    (a -> f c) -> (b -> f d) -> f a b -> f (f c d)
    forall (t :: * -> * -> *) (f :: * -> *) a c b d.
    (Bitraversable t, Applicative f) =>
    (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
    bitraverse Integer -> Triple Integer
    f1 Integer -> Triple Integer
    f2 (f Integer Integer
     -> Compose
          Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer))
    -> f Integer Integer
    -> Compose
         Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    forall a b. (a -> b) -> a -> b
    $ f Integer Integer
    x
          y' :: Compose
      Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    y' = (Integer
     -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer)
    -> (Integer
        -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer)
    -> f Integer Integer
    -> Compose
         Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    forall (f :: * -> *) a c b d.
    Applicative f =>
    (a -> f c) -> (b -> f d) -> f a b -> f (f c d)
    forall (t :: * -> * -> *) (f :: * -> *) a c b d.
    (Bitraversable t, Applicative f) =>
    (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
    bitraverse (Triple (Compose Triple (Writer (Set Integer)) Integer)
    -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer
    forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
    f (g a) -> Compose f g a
    Compose (Triple (Compose Triple (Writer (Set Integer)) Integer)
     -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer)
    -> (Integer
        -> Triple (Compose Triple (Writer (Set Integer)) Integer))
    -> Integer
    -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> Triple Integer
    -> Triple (Compose Triple (Writer (Set Integer)) Integer)
    forall a b. (a -> b) -> Triple a -> Triple b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Integer -> Compose Triple (Writer (Set Integer)) Integer
    g1 (Triple Integer
     -> Triple (Compose Triple (Writer (Set Integer)) Integer))
    -> (Integer -> Triple Integer)
    -> Integer
    -> Triple (Compose Triple (Writer (Set Integer)) Integer)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Triple Integer
    f1) (Triple (Compose Triple (Writer (Set Integer)) Integer)
    -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer
    forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
    f (g a) -> Compose f g a
    Compose (Triple (Compose Triple (Writer (Set Integer)) Integer)
     -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer)
    -> (Integer
        -> Triple (Compose Triple (Writer (Set Integer)) Integer))
    -> Integer
    -> Compose Triple (Compose Triple (Writer (Set Integer))) Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Integer -> Compose Triple (Writer (Set Integer)) Integer)
    -> Triple Integer
    -> Triple (Compose Triple (Writer (Set Integer)) Integer)
    forall a b. (a -> b) -> Triple a -> Triple b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Integer -> Compose Triple (Writer (Set Integer)) Integer
    g2 (Triple Integer
     -> Triple (Compose Triple (Writer (Set Integer)) Integer))
    -> (Integer -> Triple Integer)
    -> Integer
    -> Triple (Compose Triple (Writer (Set Integer)) Integer)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Triple Integer
    f2) f Integer Integer
    x
      in Compose
      Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    -> Compose
         Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    -> Bool
    forall (f :: * -> *) (g :: * -> * -> *) x y.
    (forall a. Eq a => Eq (f a),
     forall a b. (Eq a, Eq b) => Eq (g a b), Eq x, Eq y) =>
    f (g x y) -> f (g x y) -> Bool
    eq1_2 Compose
      Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    x' Compose
      Triple (Compose Triple (Writer (Set Integer))) (f Integer Integer)
    y'

    #endif