testBoxedZippable :: ( Eq (Element col) , Show (Item a), Show (Item b)
                     , BoxedZippable col, Zippable a, Zippable b
                     , Element col ~ (Item a, Item b) )
                  => Proxy a -> Proxy b -> Proxy col -> Gen (Element a) -> Gen (Element b) -> [TestTree]
testBoxedZippable proxyA proxyB proxyCol genElementA genElementB =
    [ testProperty "zip" $ withList2 $ \(as, bs) ->
        toListP proxyCol (zip (fromListP proxyA as) (fromListP proxyB bs)) === zip as bs
    , testProperty "zip . unzip == id" $ withListOfTuples $ \xs ->
        let (as, bs) = unzip (fromListP proxyCol xs)
        in toListP proxyCol (zip (as `asProxyTypeOf` proxyA) (bs `asProxyTypeOf` proxyB)) === xs
    ]
  where
    withList2 = forAll ((,) <$> generateListOfElement genElementA <*> generateListOfElement genElementB)
    withListOfTuples = forAll (generateListOfElement ((,) <$> genElementA <*> genElementB))
testBoxedZippable :: ( Eq (Element col) , Show (Item a), Show (Item b)
                     , BoxedZippable col, Zippable a, Zippable b
                     , Element col ~ (Item a, Item b) )
                  => Proxy a -> Proxy b -> Proxy col -> Gen (Element a) -> Gen (Element b) -> [TestTree]
testBoxedZippable proxyA proxyB proxyCol genElementA genElementB =
    [ testProperty "zip" $ withList2 $ \(as, bs) ->
        toListP proxyCol (zip (fromListP proxyA as) (fromListP proxyB bs)) === zip as bs
    , testProperty "zip . unzip == id" $ withListOfTuples $ \xs ->
        let (as, bs) = unzip (fromListP proxyCol xs)
        in toListP proxyCol (zip (as `asProxyTypeOf` proxyA) (bs `asProxyTypeOf` proxyB)) === xs
    ]
  where
    withList2 = forAll ((,) <$> generateListOfElement genElementA <*> generateListOfElement genElementB)
    withListOfTuples = forAll (generateListOfElement ((,) <$> genElementA <*> genElementB))
testBoxedZippable proxyA proxyB proxyCol genElementA genElementB =
    [ testProperty "zip" $ withList2 $ \(as, bs) ->
        toListP proxyCol (zip (fromListP proxyA as) (fromListP proxyB bs)) === zip as bs
    , testProperty "zip . unzip == id" $ withListOfTuples $ \xs ->
        let (as, bs) = unzip (fromListP proxyCol xs)
        in toListP proxyCol (zip (as `asProxyTypeOf` proxyA) (bs `asProxyTypeOf` proxyB)) === xs
    ]
  where
    withList2 = forAll ((,) <$> generateListOfElement genElementA <*> generateListOfElement genElementB)
    withListOfTuples = forAll (generateListOfElement ((,) <$> genElementA <*> genElementB))