{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Test.Massiv.VectorSpec (spec) where import Control.Arrow (first) import Control.Applicative import Control.DeepSeq import Control.Exception import Data.Bits import Data.Int import qualified Data.Tuple as Tuple import qualified Data.List as List import Data.Massiv.Array as A import Data.Massiv.Array.Unsafe as A import Data.Massiv.Vector as V import Data.Maybe import Data.Primitive.MutVar import qualified Data.Vector as VB import qualified Data.Vector.Primitive as VP import qualified Data.Vector.Storable as VS import qualified Data.Vector.Unboxed as VU import Data.Word import Test.Massiv.Core import System.Random.MWC as MWC infix 4 !==!, !!==!! sizeException :: SizeException -> Bool sizeException exc = exc `deepseq` True toUnboxV2 :: Unbox e1 => (VU.Vector e2 -> VU.Vector e3 -> VU.Vector e1) -> Array U ix1 e2 -> Array U ix2 e3 -> Array U Ix1 e1 toUnboxV2 f v1 v2 = fromUnboxedVector (f (toUnboxedVector v1) (toUnboxedVector v2)) toUnboxV3 :: Unbox e1 => (VU.Vector e -> VU.Vector e2 -> VU.Vector e3 -> VU.Vector e1) -> Array U ix e -> Array U ix1 e2 -> Array U ix2 e3 -> Array U Ix1 e1 toUnboxV3 f v1 = toUnboxV2 (f (toUnboxedVector v1)) toUnboxV4 :: Unbox e1 => (VU.Vector e2 -> VU.Vector e3 -> VU.Vector e4 -> VU.Vector e5 -> VU.Vector e1) -> Array U ix1 e2 -> Array U ix2 e3 -> Array U ix3 e4 -> Array U ix4 e5 -> Array U Ix1 e1 toUnboxV4 f v1 = toUnboxV3 (f (toUnboxedVector v1)) toUnboxV5 :: Unbox e1 => (VU.Vector e2 -> VU.Vector e3 -> VU.Vector e4 -> VU.Vector e5 -> VU.Vector e6 -> VU.Vector e1) -> Array U ix1 e2 -> Array U ix2 e3 -> Array U ix3 e4 -> Array U ix4 e5 -> Array U ix5 e6 -> Array U Ix1 e1 toUnboxV5 f v1 = toUnboxV4 (f (toUnboxedVector v1)) toUnboxV6 :: Unbox e1 => (VU.Vector e2 -> VU.Vector e3 -> VU.Vector e4 -> VU.Vector e5 -> VU.Vector e6 -> VU.Vector e7 -> VU.Vector e1) -> Array U ix1 e2 -> Array U ix2 e3 -> Array U ix3 e4 -> Array U ix4 e5 -> Array U ix5 e6 -> Array U ix6 e7 -> Array U Ix1 e1 toUnboxV6 f v1 = toUnboxV5 (f (toUnboxedVector v1)) toPrimV2 :: (Index ix) => (VP.Vector e1 -> VP.Vector e2 -> t) -> Array P ix e1 -> Array P ix e2 -> t toPrimV2 f v1 v2 = f (toPrimitiveVector v1) (toPrimitiveVector v2) toPrimV3 :: Index ix => (VP.Vector e -> VP.Vector e1 -> VP.Vector e2 -> t) -> Array P ix e -> Array P ix e1 -> Array P ix e2 -> t toPrimV3 f v1 = toPrimV2 (f (toPrimitiveVector v1)) toPrimV4 :: Index ix => (VP.Vector e1 -> VP.Vector e2 -> VP.Vector e3 -> VP.Vector e4 -> t) -> Array P ix e1 -> Array P ix e2 -> Array P ix e3 -> Array P ix e4 -> t toPrimV4 f v1 = toPrimV3 (f (toPrimitiveVector v1)) toPrimV5 :: Index ix => (VP.Vector e -> VP.Vector e1 -> VP.Vector e2 -> VP.Vector e3 -> VP.Vector e4 -> t) -> Array P ix e -> Array P ix e1 -> Array P ix e2 -> Array P ix e3 -> Array P ix e4 -> t toPrimV5 f v1 = toPrimV4 (f (toPrimitiveVector v1)) toPrimV6 :: Index ix => (VP.Vector e -> VP.Vector e1 -> VP.Vector e2 -> VP.Vector e3 -> VP.Vector e4 -> VP.Vector e5 -> t) -> Array P ix e -> Array P ix e1 -> Array P ix e2 -> Array P ix e3 -> Array P ix e4 -> Array P ix e5 -> t toPrimV6 f v1 = toPrimV5 (f (toPrimitiveVector v1)) (!==!) :: (Eq e, Show e, Prim e, Load r Ix1 e) => V.Vector r e -> VP.Vector e -> Property (!==!) arr vec = toPrimitiveVector (convert arr) === vec (!!==!!) :: (Eq e, Show e, Prim e, Source r Ix1 e) => V.Vector r e -> VP.Vector e -> Property (!!==!!) arr vec = property $ do eRes <- try (pure $! vec) case eRes of Right vec' -> toPrimitiveVector (computeSource arr) `shouldBe` vec' Left (_exc :: ErrorCall) -> shouldThrow (pure $! computeAs P arr) sizeException newtype SeedVector = SeedVector (VP.Vector Word32) deriving (Eq, Show) instance Arbitrary SeedVector where arbitrary = SeedVector . VP.fromList <$> arbitrary withSeed :: forall a. SeedVector -> (forall s. MWC.Gen s -> ST s a) -> a withSeed (SeedVector seed) f = runST $ MWC.initialize seed >>= f withSeed2 :: forall a. (Eq a, Show a) => SeedVector -> (forall s. MWC.Gen s -> ST s a) -> (forall s. MWC.Gen s -> ST s a) -> Property withSeed2 seed f g = withSeed @a seed f === withSeed seed g withSeedV2 :: forall r e. (Eq e, Show e, Prim e, Load r Ix1 e) => SeedVector -> (forall s. MWC.Gen s -> ST s (V.Vector r e)) -> (forall s. MWC.Gen s -> ST s (VP.Vector e)) -> Property withSeedV2 seed f g = withSeed @(V.Vector r e) seed f !==! withSeed seed g prop_sreplicateM :: SeedVector -> Int -> Property prop_sreplicateM seed k = withSeedV2 @DS @Word seed (V.sreplicateM (Sz k) . uniform) (VP.replicateM k . uniform) prop_sgenerateM :: SeedVector -> Int -> Fun Int Word -> Property prop_sgenerateM seed k f = withSeedV2 @DS @Word seed (genWith (V.sgenerateM (Sz k))) (genWith (VP.generateM k)) where genWith :: PrimMonad f => ((Int -> f Word) -> t) -> MWC.Gen (PrimState f) -> t genWith genM gen = genM (\i -> xor (apply f i) <$> uniform gen) prop_siterateNM :: SeedVector -> Int -> Word -> Property prop_siterateNM seed k a = withSeed @(V.Vector DS Word) seed (genWith (\f -> V.siterateNM (Sz k) f a)) !==! withSeed seed (genWith (\f -> VP.iterateNM k f a)) where genWith :: PrimMonad f => ((Word -> f Word) -> t) -> MWC.Gen (PrimState f) -> t genWith genM gen = genM (\prev -> xor prev <$> uniform gen) genWithUnfoldrM :: PrimMonad f => ((Word -> f (Maybe (Word, Word))) -> t) -> MWC.Gen (PrimState f) -> t genWithUnfoldrM genM gen = genM $ \prev -> do x <- uniform gen let cur = prev `xor` x pure $ if cur `mod` 17 == 0 then Nothing else Just (x, cur) prop_sunfoldrM :: SeedVector -> Word -> Property prop_sunfoldrM seed a = withSeedV2 @DS @Word seed (genWithUnfoldrM (`V.sunfoldrM` a)) (genWithUnfoldrM (`VP.unfoldrM`a)) prop_sunfoldrNM :: SeedVector -> Int -> Word -> Property prop_sunfoldrNM seed k a = withSeedV2 @DS @Word seed (genWithUnfoldrM (\f -> V.sunfoldrNM (Sz k) f a)) (genWithUnfoldrM (\f -> VP.unfoldrNM k f a)) .&&. withSeedV2 @DS @Word seed (genWithUnfoldrM (\f -> A.unsafeUnfoldrNM (Sz k) f a)) (genWithUnfoldrM (\f -> VP.unfoldrNM k f a)) prop_sunfoldrExactNM :: SeedVector -> Int -> Word -> Property prop_sunfoldrExactNM seed k a = withSeedV2 @DS @Word seed (genWith (\f -> V.sunfoldrExactNM (Sz k) f a)) (genWith (\f -> VP.unfoldrNM k (fmap Just . f) a)) where genWith :: PrimMonad f => ((Word -> f (Word, Word)) -> t) -> MWC.Gen (PrimState f) -> t genWith genM gen = genM $ \prev -> do x <- uniform gen pure (x, prev `xor` x) genWithMapM :: PrimMonad m => ((Word -> m Word) -> m a) -> MWC.Gen (PrimState m) -> m a genWithMapM genM gen = genM $ \e -> xor e <$> uniform gen genWithMapWS :: PrimMonad m => ((Word -> MWC.Gen (PrimState m) -> m Word) -> m a) -> m a genWithMapWS genM = genM $ \e gen -> xor e <$> uniform gen genWithIMapM :: PrimMonad m => ((Int -> Word -> m Word) -> m a) -> MWC.Gen (PrimState m) -> m a genWithIMapM genM gen = genM $ \i e -> do ir <- uniformR (0, fromIntegral i) gen xor ir . xor e <$> uniform gen genWithIMapWS :: PrimMonad m => ((Int -> Word -> MWC.Gen (PrimState m) -> m Word) -> m a) -> m a genWithIMapWS genM = genM $ \i e gen -> do ir <- uniformR (0, fromIntegral i) gen xor ir . xor e <$> uniform gen genWithMapM_ :: PrimMonad m => ((Word -> m ()) -> m ()) -> MWC.Gen (PrimState m) -> m Word genWithMapM_ genM gen = do ref <- newMutVar =<< uniform gen genM $ \e -> do e' <- xor e <$> uniform gen modifyMutVar ref (xor e') readMutVar ref genWithIMapM_ :: PrimMonad m => ((Int -> Word -> m ()) -> m ()) -> MWC.Gen (PrimState m) -> m Word genWithIMapM_ genM gen = do ref <- newMutVar =<< uniform gen genM $ \i e -> do ir <- uniformR (0, fromIntegral i) gen e' <- xor ir . xor e <$> uniform gen modifyMutVar ref (xor e') readMutVar ref prop_straverse :: SeedVector -> Array P Ix2 Word -> Property prop_straverse seed a = withSeed @(V.Vector DS Word) seed (genWithMapM (`V.straverse` a)) !==! withSeed seed (genWithMapM (`VP.mapM` toPrimitiveVector a)) prop_smapM :: SeedVector -> Array P Ix2 Word -> Property prop_smapM seed a = withSeed @(V.Vector DS Word) seed (genWithMapM (`V.smapM` a)) !==! withSeed seed (genWithMapM (`VP.mapM` toPrimitiveVector a)) prop_smapMaybeM :: SeedVector -> Array B Ix2 Word -> Fun Word (Maybe Word16) -> Property prop_smapMaybeM seed a gm = withSeed @(V.Vector DS Word16) seed (genWithMapM (\ f -> V.smapMaybeM (fmap g . f) a)) !==! withSeed seed (genWithMapM (\f -> VP.convert . VB.mapMaybe id <$> VB.mapM (fmap g . f) (toBoxedVector a))) where g = apply gm prop_sitraverse :: SeedVector -> Vector P Word -> Property prop_sitraverse seed a = withSeed @(V.Vector DS Word) seed (genWithIMapM (`V.sitraverse` a)) !==! withSeed seed (genWithIMapM (\f -> VP.convert <$> VU.mapM (uncurry f) vp)) where vp = VU.imap (,) $ toUnboxedVector (compute a) prop_simapM :: SeedVector -> Vector U Word -> Property prop_simapM seed a = withSeed @(V.Vector DS Word) seed (genWithIMapM (V.siforM a)) !==! withSeed seed (genWithIMapM (\f -> VP.convert <$> VU.mapM (uncurry f) vp)) where vp = VU.imap (,) $ toUnboxedVector a prop_smapM_ :: SeedVector -> Array P Ix2 Word -> Property prop_smapM_ seed a = withSeed seed (genWithMapM_ (V.sforM_ a)) === withSeed seed (genWithMapM_ (VP.forM_ (toPrimitiveVector a))) prop_simapM_ :: SeedVector -> Vector U Word -> Property prop_simapM_ seed a = withSeed seed (genWithIMapM_ (V.siforM_ a)) === withSeed seed (genWithIMapM_ (\f -> VU.mapM_ (uncurry f) vp)) where vp = VU.imap (,) $ toUnboxedVector a prop_sfilterM :: SeedVector -> Fun Word Bool -> Vector P Word -> Property prop_sfilterM seed g a = withSeed @(V.Vector DS Word) seed (genWith (`V.sfilterM` a)) !==! withSeed seed (genWith (`VP.filterM` toPrimitiveVector a)) where genWith :: PrimMonad f => ((Word -> f Bool) -> t) -> MWC.Gen (PrimState f) -> t genWith genM gen = genM $ \e -> do x <- xor e <$> uniform gen pure $ apply g x prop_sifilterM :: SeedVector -> Fun Word Bool -> Vector U Word -> Property prop_sifilterM seed g a = withSeed @(V.Vector DS Word) seed (genWith (`V.sifilterM` a)) !==! withSeed seed (genWith (\f -> VP.convert . VU.map snd <$> VU.filterM (uncurry f) vp)) where vp = VU.imap (,) $ toUnboxedVector a genWith :: PrimMonad f => ((Int -> Word -> f Bool) -> t) -> MWC.Gen (PrimState f) -> t genWith genM gen = genM $ \i e -> do ir <- uniformR (0, fromIntegral i) gen x <- xor ir . xor e <$> uniform gen pure $ apply g x applyFun4 :: Fun (a, b, c, d) e -> (a -> b -> c -> d -> e) applyFun4 (Fun _ f) a b c d = f (a, b, c, d) applyFun5 :: Fun (a, b, c, d, e) f -> (a -> b -> c -> d -> e -> f) applyFun5 (Fun _ g) a b c d f = g (a, b, c, d, f) applyFun6 :: Fun (a, (b, c, d, e, f)) g -> (a -> b -> c -> d -> e -> f -> g) applyFun6 (Fun _ h) a b c d f g = h (a, (b, c, d, f, g)) applyFun7 :: Fun (a, b, (c, d, e, f, g)) h -> (a -> b -> c -> d -> e -> f -> g -> h) applyFun7 (Fun _ i) a b c d f g h = i (a, b, (c, d, f, g, h)) com2M :: Fun (a, b) d -> (d -> c) -> a -> b -> c com2M f g a = g . applyFun2 f a com3M :: Fun (a, b, c) d -> (d -> e) -> a -> b -> c -> e com3M f g a b = g . applyFun3 f a b com4M :: Fun (a, b, c, d) e -> (e -> h) -> a -> b -> c -> d -> h com4M f g a b c = g . applyFun4 f a b c com5M :: Fun (a, b, c, d, e) h -> (h -> i) -> a -> b -> c -> d -> e -> i com5M f g a b c d = g . applyFun5 f a b c d com6M :: Fun (a, (b, c, d, e, h)) i -> (i -> j) -> a -> b -> c -> d -> e -> h -> j com6M f g a b c d e = g . applyFun6 f a b c d e com7M :: Fun (a, b, (c, d, e, h, i)) j -> (j -> k) -> a -> b -> c -> d -> e -> h -> i -> k com7M f g a b c d e h = g . applyFun7 f a b c d e h prop_szip :: Vector U Word -> Vector U Int -> Property prop_szip v1 v2 = compute (V.szip v1 v2) === toUnboxV2 VU.zip v1 v2 prop_szip3 :: Vector U Word64 -> Vector U Word32 -> Vector U Word16 -> Property prop_szip3 v1 v2 v3 = compute (V.szip3 v1 v2 v3) === toUnboxV3 VU.zip3 v1 v2 v3 prop_szip4 :: Vector U Word64 -> Vector U Word32 -> Vector U Word16 -> Vector U Word8 -> Property prop_szip4 v1 v2 v3 v4 = compute (V.szip4 v1 v2 v3 v4) === toUnboxV4 VU.zip4 v1 v2 v3 v4 prop_szip5 :: Vector U Word64 -> Vector U Word32 -> Vector U Word16 -> Vector U Word8 -> Vector U Int8 -> Property prop_szip5 v1 v2 v3 v4 v5 = compute (V.szip5 v1 v2 v3 v4 v5) === toUnboxV5 VU.zip5 v1 v2 v3 v4 v5 prop_szip6 :: Vector U Word64 -> Vector U Word32 -> Vector U Word16 -> Vector U Word8 -> Vector U Int8 -> Vector U Int16 -> Property prop_szip6 v1 v2 v3 v4 v5 v6 = compute (V.szip6 v1 v2 v3 v4 v5 v6) === toUnboxV6 VU.zip6 v1 v2 v3 v4 v5 v6 prop_szipWith :: Vector P Word -> Vector P Int -> Fun (Word, Int) Int -> Property prop_szipWith v1 v2 f = V.szipWith (applyFun2 f) v1 v2 !==! toPrimV2 (VP.zipWith (applyFun2 f)) v1 v2 prop_szipWith3 :: Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Fun (Word64, Word32, Word16) Int -> Property prop_szipWith3 v1 v2 v3 f = V.szipWith3 (applyFun3 f) v1 v2 v3 !==! toPrimV3 (VP.zipWith3 (applyFun3 f)) v1 v2 v3 prop_szipWith4 :: Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Fun (Word64, Word32, Word16, Word8) Int -> Property prop_szipWith4 v1 v2 v3 v4 f = V.szipWith4 (applyFun4 f) v1 v2 v3 v4 !==! toPrimV4 (VP.zipWith4 (applyFun4 f)) v1 v2 v3 v4 prop_szipWith5 :: Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Word64, Word32, Word16, Word8, Int8) Int -> Property prop_szipWith5 v1 v2 v3 v4 v5 f = V.szipWith5 (applyFun5 f) v1 v2 v3 v4 v5 !==! toPrimV5 (VP.zipWith5 (applyFun5 f)) v1 v2 v3 v4 v5 prop_szipWith6 :: Vector DS Word64 -> Vector B Word32 -> Vector N Word16 -> Vector S Word8 -> Vector U Int8 -> Vector P Int16 -> Fun (Word64, (Word32, Word16, Word8, Int8, Int16)) Int -> Property prop_szipWith6 v1 v2 v3 v4 v5 v6 f = V.szipWith6 (applyFun6 f) v1 v2 v3 v4 v5 v6 !==! toPrimV6 (VP.zipWith6 (applyFun6 f)) (compute v1) (compute v2) (compute v3) (compute v4) (compute v5) v6 prop_sizipWith :: Vector DS Word64 -> Vector DS Word32 -> Fun (Ix1, Word64, Word32) Int -> Property prop_sizipWith v1 v2 f = sizipWith (applyFun3 f) v1 v2 !==! toPrimV2 (VP.izipWith (applyFun3 f)) (compute v1) (compute v2) prop_sizipWith3 :: Vector P Word64 -> Vector D Word32 -> Vector D Word16 -> Fun (Ix1, Word64, Word32, Word16) Int -> Property prop_sizipWith3 v1 v2 v3 f = sizipWith3 (applyFun4 f) v1 v2 v3 !==! toPrimV3 (VP.izipWith3 (applyFun4 f)) (compute v1) (compute v2) (compute v3) prop_sizipWith4 :: Vector D Word64 -> Vector DS Word32 -> Vector P Word16 -> Vector U Word8 -> Fun (Ix1, Word64, Word32, Word16, Word8) Int -> Property prop_sizipWith4 v1 v2 v3 v4 f = sizipWith4 (applyFun5 f) v1 v2 v3 v4 !==! toPrimV4 (VP.izipWith4 (applyFun5 f)) (compute v1) (compute v2) (compute v3) (compute v4) prop_sizipWith5 :: Vector DS Word64 -> Vector S Word32 -> Vector P Word16 -> Vector U Word8 -> Vector N Int8 -> Fun (Ix1, (Word64, Word32, Word16, Word8, Int8)) Int -> Property prop_sizipWith5 v1 v2 v3 v4 v5 f = sizipWith5 (applyFun6 f) v1 v2 v3 v4 v5 !==! toPrimV5 (VP.izipWith5 (applyFun6 f)) (compute v1) (compute v2) v3 (compute v4) (compute v5) prop_sizipWith6 :: Vector DS Word64 -> Vector D Word32 -> Vector B Word16 -> Vector N Word8 -> Vector P Int8 -> Vector P Int16 -> Fun (Ix1, Word64, (Word32, Word16, Word8, Int8, Int16)) Int -> Property prop_sizipWith6 v1 v2 v3 v4 v5 v6 f = sizipWith6 (applyFun7 f) v1 v2 v3 v4 v5 v6 !==! toPrimV6 (VP.izipWith6 (applyFun7 f)) (compute v1) (compute v2) (compute v3) (compute v4) v5 v6 prop_szipWithM :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Fun (Word64, Word32) Word -> Property prop_szipWithM seed v1 v2 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.szipWithM (com2M f g) v1 v2)) (genWithMapM (\g -> toPrimV2 (VP.zipWithM (com2M f g)) v1 v2)) prop_szipWith3M :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Fun (Word64, Word32, Word16) Word -> Property prop_szipWith3M seed v1 v2 v3 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.szipWith3M (com3M f g) v1 v2 v3)) (genWithMapM (VP.forM (toPrimV3 (VP.zipWith3 (applyFun3 f)) v1 v2 v3))) prop_szipWith4M :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Fun (Word64, Word32, Word16, Word8) Word -> Property prop_szipWith4M seed v1 v2 v3 v4 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.szipWith4M (com4M f g) v1 v2 v3 v4)) (genWithMapM (VP.forM (toPrimV4 (VP.zipWith4 (applyFun4 f)) v1 v2 v3 v4))) prop_szipWith5M :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Word64, Word32, Word16, Word8, Int8) Word -> Property prop_szipWith5M seed v1 v2 v3 v4 v5 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.szipWith5M (com5M f g) v1 v2 v3 v4 v5)) (genWithMapM (VP.forM (toPrimV5 (VP.zipWith5 (applyFun5 f)) v1 v2 v3 v4 v5))) prop_szipWith6M :: SeedVector -> Vector P Int16 -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Int16, (Word64, Word32, Word16, Word8, Int8)) Word -> Property prop_szipWith6M seed v1 v2 v3 v4 v5 v6 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.szipWith6M (com6M f g) v1 v2 v3 v4 v5 v6)) (genWithMapM (VP.forM (toPrimV6 (VP.zipWith6 (applyFun6 f)) v1 v2 v3 v4 v5 v6))) prop_szipWithM_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Fun (Word64, Word32) Word -> Property prop_szipWithM_ seed v1 v2 f = withSeed2 seed (genWithMapM_ (\g -> V.szipWithM_ (com2M f g) v1 v2)) (genWithMapM_ (\g -> toPrimV2 (VP.zipWithM_ (com2M f g)) v1 v2)) prop_szipWith3M_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Fun (Word64, Word32, Word16) Word -> Property prop_szipWith3M_ seed v1 v2 v3 f = withSeed2 seed (genWithMapM_ (\g -> V.szipWith3M_ (com3M f g) v1 v2 v3)) (genWithMapM_ (VP.forM_ (toPrimV3 (VP.zipWith3 (applyFun3 f)) v1 v2 v3))) prop_szipWith4M_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Fun (Word64, Word32, Word16, Word8) Word -> Property prop_szipWith4M_ seed v1 v2 v3 v4 f = withSeed2 seed (genWithMapM_ (\g -> V.szipWith4M_ (com4M f g) v1 v2 v3 v4)) (genWithMapM_ (VP.forM_ (toPrimV4 (VP.zipWith4 (applyFun4 f)) v1 v2 v3 v4))) prop_szipWith5M_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Word64, Word32, Word16, Word8, Int8) Word -> Property prop_szipWith5M_ seed v1 v2 v3 v4 v5 f = withSeed2 seed (genWithMapM_ (\g -> V.szipWith5M_ (com5M f g) v1 v2 v3 v4 v5)) (genWithMapM_ (VP.forM_ (toPrimV5 (VP.zipWith5 (applyFun5 f)) v1 v2 v3 v4 v5))) prop_szipWith6M_ :: SeedVector -> Vector P Int16 -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Int16, (Word64, Word32, Word16, Word8, Int8)) Word -> Property prop_szipWith6M_ seed v1 v2 v3 v4 v5 v6 f = withSeed2 seed (genWithMapM_ (\g -> V.szipWith6M_ (com6M f g) v1 v2 v3 v4 v5 v6)) (genWithMapM_ (VP.forM_ (toPrimV6 (VP.zipWith6 (applyFun6 f)) v1 v2 v3 v4 v5 v6))) prop_sizipWithM :: SeedVector -> Vector U Word64 -> Vector U Word32 -> Fun (Ix1, Word64, Word32) Word -> Property prop_sizipWithM seed v1 v2 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.sizipWithM (com3M f g) v1 v2)) (genWithMapM (\g -> VP.convert <$> VU.izipWithM (com3M f g) (toUnboxedVector v1) (toUnboxedVector v2))) prop_sizipWith3M :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Fun (Ix1, Word64, Word32, Word16) Word -> Property prop_sizipWith3M seed v1 v2 v3 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.sizipWith3M (com4M f g) v1 v2 v3)) (genWithMapM (VP.forM (toPrimV3 (VP.izipWith3 (applyFun4 f)) v1 v2 v3))) prop_sizipWith4M :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Fun (Ix1, Word64, Word32, Word16, Word8) Word -> Property prop_sizipWith4M seed v1 v2 v3 v4 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.sizipWith4M (com5M f g) v1 v2 v3 v4)) (genWithMapM (VP.forM (toPrimV4 (VP.izipWith4 (applyFun5 f)) v1 v2 v3 v4))) prop_sizipWith5M :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Ix1, (Word64, Word32, Word16, Word8, Int8)) Word -> Property prop_sizipWith5M seed v1 v2 v3 v4 v5 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.sizipWith5M (com6M f g) v1 v2 v3 v4 v5)) (genWithMapM (VP.forM (toPrimV5 (VP.izipWith5 (applyFun6 f)) v1 v2 v3 v4 v5))) prop_sizipWith6M :: SeedVector -> Vector P Int16 -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Ix1, Int16, (Word64, Word32, Word16, Word8, Int8)) Word -> Property prop_sizipWith6M seed v1 v2 v3 v4 v5 v6 f = withSeedV2 @DS @Word seed (genWithMapM (\g -> V.sizipWith6M (com7M f g) v1 v2 v3 v4 v5 v6)) (genWithMapM (VP.forM (toPrimV6 (VP.izipWith6 (applyFun7 f)) v1 v2 v3 v4 v5 v6))) prop_sizipWithM_ :: SeedVector -> Vector U Word64 -> Vector U Word32 -> Fun (Ix1, Word64, Word32) Word -> Property prop_sizipWithM_ seed v1 v2 f = withSeed2 seed (genWithMapM_ (\g -> V.sizipWithM_ (com3M f g) v1 v2)) (genWithMapM_ (\g -> VU.izipWithM_ (com3M f g) (toUnboxedVector v1) (toUnboxedVector v2))) prop_sizipWith3M_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Fun (Ix1, Word64, Word32, Word16) Word -> Property prop_sizipWith3M_ seed v1 v2 v3 f = withSeed2 seed (genWithMapM_ (\g -> V.sizipWith3M_ (com4M f g) v1 v2 v3)) (genWithMapM_ (VP.forM_ (toPrimV3 (VP.izipWith3 (applyFun4 f)) v1 v2 v3))) prop_sizipWith4M_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Fun (Ix1, Word64, Word32, Word16, Word8) Word -> Property prop_sizipWith4M_ seed v1 v2 v3 v4 f = withSeed2 seed (genWithMapM_ (\g -> V.sizipWith4M_ (com5M f g) v1 v2 v3 v4)) (genWithMapM_ (VP.forM_ (toPrimV4 (VP.izipWith4 (applyFun5 f)) v1 v2 v3 v4))) prop_sizipWith5M_ :: SeedVector -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Ix1, (Word64, Word32, Word16, Word8, Int8)) Word -> Property prop_sizipWith5M_ seed v1 v2 v3 v4 v5 f = withSeed2 seed (genWithMapM_ (\g -> V.sizipWith5M_ (com6M f g) v1 v2 v3 v4 v5)) (genWithMapM_ (VP.forM_ (toPrimV5 (VP.izipWith5 (applyFun6 f)) v1 v2 v3 v4 v5))) prop_sizipWith6M_ :: SeedVector -> Vector P Int16 -> Vector P Word64 -> Vector P Word32 -> Vector P Word16 -> Vector P Word8 -> Vector P Int8 -> Fun (Ix1, Int16, (Word64, Word32, Word16, Word8, Int8)) Word -> Property prop_sizipWith6M_ seed v1 v2 v3 v4 v5 v6 f = withSeed2 seed (genWithMapM_ (\g -> V.sizipWith6M_ (com7M f g) v1 v2 v3 v4 v5 v6)) (genWithMapM_ (VP.forM_ (toPrimV6 (VP.izipWith6 (applyFun7 f)) v1 v2 v3 v4 v5 v6))) spec :: Spec spec = describe "Vector" $ do describe "same-as-array" $ do describe "traverse" $ do prop "straverse == traversePrim" prop_straverse_traversePrim prop "sitraverse == itraversePrim" prop_sitraverse_itraversePrim prop "sitraverse == itraverseA" prop_sitraverse_itraverseA prop "simapM_ == itraverseA_" prop_simapM_itraverseA_ prop "smapM_ == traverseA_" prop_smapM_traverseA_ prop "sforM == forM" prop_sforM_forM prop "siforM == iforM" prop_siforM_iforM prop "sforM_ == forM_" prop_sforM_forM_ prop "siforM_ == iforM_" prop_siforM_iforM_ prop "sforM_ == forIO_ (ParN 1)" prop_sforM_forIO_ prop "sforM == forIO (Seq)" prop_sforM_forIO prop "siforM == iforIO (ParN 1)" prop_siforM_iforIO prop "siforM == iforIO_ (ParN 1)" prop_siforM_iforIO_ prop "siforM == iforWS (ParN 1)" prop_siforM_iforWS prop "smapM == mapWS (Seq)" prop_smapM_mapWS describe "Enumeration" $ do prop "senumFromN" $ \comp (i :: Int) sz -> computeAs S (V.senumFromN i sz) === compute (A.enumFromN comp i sz) prop "senumFromStepN" $ \comp (i :: Int) s sz -> computeAs S (V.senumFromStepN i s sz) === compute (A.enumFromStepN comp i s sz) describe "same-as-vector-package" $ do describe "Accessors" $ do describe "Size" $ do it "slength" $ do slength (sfromList []) `shouldBe` Nothing slength (sfromListN 1 []) `shouldBe` Nothing slength (sgenerate 1 id) `shouldBe` Just 1 it "snull" $ do snull sempty `shouldBe` True snull (fromLists' Seq [[]] :: Array P Ix2 Int) `shouldBe` True snull (siterateN 3 id ()) `shouldBe` False snull (0 ..: 1 :> 2 :> 3 :. 0) `shouldBe` True describe "Indexing" $ do prop "head' (non-empty)" $ \(ArrNE arr :: ArrNE D Ix1 Int) -> head' arr === evaluate' arr 0 .&&. head' arr === shead' arr prop "head'" $ \(arr :: Array D Ix1 Int) -> (singleton (head' arr) :: Array D Ix1 Int) !!==!! VP.singleton (VP.head (toPrimitiveVector (compute arr))) prop "shead'" $ \(arr :: Array P Ix1 Int) -> (singleton (shead' arr) :: Array D Ix1 Int) !!==!! VP.singleton (VP.head (toPrimitiveVector arr)) prop "last'" $ \(arr :: Array P Ix1 Int) -> (singleton (last' arr) :: Array D Ix1 Int) !!==!! VP.singleton (VP.last (toPrimitiveVector arr)) prop "unconsM" $ \(v :: Vector D Int) -> fmap (computeAs P <$>) (A.unconsM v :: Maybe (Int, Vector D Int)) === fmap (fmap (A.fromList Seq)) (List.uncons (A.toList v)) prop "unsnocM" $ \(v :: Vector D Int) -> fmap (first (computeAs P)) (A.unsnocM v :: Maybe (Vector D Int, Int)) === fmap (Tuple.swap . fmap (A.fromList Seq . List.reverse)) (List.uncons (A.toList (A.reverse Dim1 v))) describe "Slicing" $ do prop "slice" $ \i sz (arr :: Array P Ix1 Word) -> V.slice i sz arr !!==!! VP.take (unSz sz) (VP.drop i (toPrimitiveVector arr)) prop "sslice" $ \i sz (arr :: Array P Ix1 Word) -> computeAs B (V.sslice i sz arr) !!==!! VP.take (unSz sz) (VP.drop i (toPrimitiveVector arr)) prop "slice'" $ \i sz (arr :: Array P Ix1 Word) -> V.slice' i sz arr !!==!! VP.slice i (unSz sz) (toPrimitiveVector arr) prop "init" $ \(arr :: Array P Ix1 Word) -> V.init arr !==! VP.reverse (VP.drop 1 (VP.reverse (toPrimitiveVector arr))) prop "init'" $ \(arr :: Array P Ix1 Word) -> V.init' arr !!==!! VP.init (toPrimitiveVector arr) prop "tail" $ \(arr :: Array P Ix1 Word) -> let vp = toPrimitiveVector arr in (V.tail arr !==! VP.drop 1 vp) .&&. (not (isEmpty arr) ==> V.tail arr !==! VP.tail vp) prop "tail'" $ \(arr :: Array P Ix1 Word) -> V.tail' arr !!==!! VP.tail (toPrimitiveVector arr) prop "take" $ \n (arr :: Array P Ix1 Word) -> V.take (Sz n) arr !==! VP.take n (toPrimitiveVector arr) prop "take'" $ \sz@(Sz n) (arr :: Array P Ix1 Word) -> V.take' sz arr !!==!! VP.slice 0 n (toPrimitiveVector arr) prop "stake" $ \n (arr :: Array P Ix1 Word) -> V.stake (Sz n) arr !==! VP.take n (toPrimitiveVector arr) prop "drop" $ \n (arr :: Array P Ix1 Word) -> V.drop (Sz n) arr !==! VP.drop n (toPrimitiveVector arr) prop "drop'" $ \sz@(Sz n) (arr :: Array P Ix1 Word) -> V.drop' sz arr !!==!! VP.slice n (unSz (size arr) - n) (toPrimitiveVector arr) prop "sdrop" $ \n (arr :: Array P Ix1 Word) -> V.sdrop (Sz n) arr !==! VP.drop n (toPrimitiveVector arr) prop "sliceAt" $ \sz (arr :: Array P Ix1 Word) -> let (larr, rarr) = V.sliceAt (Sz sz) arr (lvec, rvec) = VP.splitAt sz (toPrimitiveVector arr) in (larr !==! lvec) .&&. (rarr !==! rvec) prop "sliceAt'" $ \sz@(Sz n) (arr :: Array P Ix1 Word) -> let (larr, rarr) = V.sliceAt' sz arr lvec = VP.slice 0 n (toPrimitiveVector arr) rvec = VP.slice n (unSz (size arr) - n) (toPrimitiveVector arr) in (larr !!==!! lvec) .&&. (rarr !!==!! rvec) describe "Constructors" $ do describe "Initialization" $ do it "empty" $ toPrimitiveVector (V.empty :: V.Vector P Word) `shouldBe` VP.empty it "sempty" $ toPrimitiveVector (compute (V.sempty :: V.Vector DS Word)) `shouldBe` VP.empty prop "singleton" $ \e -> (V.singleton e :: V.Vector P Word) !==! VP.singleton e prop "ssingleton" $ \(e :: Word) -> V.ssingleton e !==! VP.singleton e prop "replicate" $ \comp k (e :: Word) -> V.replicate comp (Sz k) e !==! VP.replicate k e prop "sreplicate" $ \k (e :: Word) -> V.sreplicate (Sz k) e !==! VP.replicate k e prop "generate" $ \comp k (f :: Fun Int Word) -> V.generate comp (Sz k) (apply f) !==! VP.generate k (apply f) prop "sgenerate" $ \k (f :: Fun Int Word) -> V.sgenerate (Sz k) (apply f) !==! VP.generate k (apply f) prop "siterateN" $ \n (f :: Fun Word Word) a -> V.siterateN (Sz n) (apply f) a !==! VP.iterateN n (apply f) a prop "siterate" $ \n (f :: Fun Word Word) a -> computeAs P (V.stake n (V.siterate (apply f) a)) === computeAs P (V.siterateN n (apply f) a) prop "cons" $ \e (v :: Vector P Word) -> computeAs P (V.cons e (toLoadArray v)) !!==!! VP.cons e (toPrimitiveVector v) describe "Monadic initialization" $ do prop "sreplicateM" prop_sreplicateM prop "sgenerateM" prop_sgenerateM prop "siterateNM" prop_siterateNM describe "Unfolding" $ do prop "sunfoldr" $ \(a :: Word) -> let f b | b > 10000 || b `div` 17 == 0 = Nothing | otherwise = Just (b * b, b + 1) in V.sunfoldr f a !==! VP.unfoldr f a prop "sunfoldrN" $ \n (a :: Word) -> let f b | b > 10000 || b `div` 19 == 0 = Nothing | otherwise = Just (b * b, b + 1) in V.sunfoldrN (Sz n) f a !==! VP.unfoldrN n f a .&&. A.unsafeUnfoldrN (Sz n) f a !==! VP.unfoldrN n f a it "sunfoldrN (maxBound)" $ let maxv = V.sunfoldrN (Sz maxBound) (const (Nothing :: Maybe (Word8, Word8))) 0 in computeAs P maxv `shouldBe` A.empty prop "sunfoldrExactN" $ \n (a :: Word) -> let f b = (b * b, b + 1) in V.sunfoldrExactN (Sz n) f a !==! VP.unfoldrN n (Just . f) a prop "sunfoldrM" prop_sunfoldrM prop "sunfoldrNM" prop_sunfoldrNM it "sunfoldrNM (maxBound)" $ let maxv = V.sunfoldrNM (Sz maxBound) (pure . const (Nothing :: Maybe (Word8, Word8))) 0 in computeAs P <$> maxv `shouldReturn` A.empty prop "sunfoldrExactM" prop_sunfoldrExactNM describe "Enumeration" $ do prop "senumFromN" $ \(i :: Int) n -> V.senumFromN i (Sz n) !==! VP.enumFromN i n prop "senumFromStepN" $ \(i :: Int) s n -> V.senumFromStepN i s (Sz n) !==! VP.enumFromStepN i s n describe "Concatenation" $ do prop "sappend" $ \(v1 :: Vector D Int) (v2 :: Vector P Int) -> V.sappend v1 v2 !==! toPrimitiveVector (compute v1) VP.++ toPrimitiveVector v2 prop "sconcat" $ \(vs :: [Vector P Int]) -> V.sconcat vs !==! VP.concat (fmap toPrimitiveVector vs) describe "Predicates" $ do describe "Filtering" $ do prop "sfilter" $ \(v :: Vector P Word) (f :: Fun Word Bool) -> V.sfilter (apply f) v !==! VP.filter (apply f) (toPrimitiveVector v) prop "sifilter" $ \(v :: Vector P Word) (f :: Fun (Int, Word) Bool) -> V.sifilter (applyFun2 f) v !==! VP.ifilter (applyFun2 f) (toPrimitiveVector v) prop "sfilterM" prop_sfilterM prop "sifilterM" prop_sifilterM prop "smapMaybe" $ \(v :: Vector P Word) (f :: Fun Word (Maybe Int)) -> V.smapMaybe (apply f) v !==! VP.mapMaybe (apply f) (toPrimitiveVector v) prop "simapMaybe" $ \(v :: Vector P Word) (f :: Fun (Int, Word) (Maybe Int)) -> V.simapMaybe (applyFun2 f) v !==! VP.imapMaybe (applyFun2 f) (toPrimitiveVector v) prop "scatMaybes" $ \(v :: Vector D (Maybe Word)) -> V.scatMaybes v !==! toPrimitiveVector (compute (smap fromJust (sfilter isJust v))) prop "smapMaybeM" prop_smapMaybeM describe "Mapping" $ do prop "fmap" $ \(v :: Vector DS Word) (f :: Fun Word Int) -> fmap (apply f) v !==! VP.map (apply f) (toPrimitiveVector (compute v)) prop "<$" $ \(v :: Vector DS Word) (a :: Char) -> (a <$ v) !==! VP.replicate (totalElem (size v)) a prop "smap" $ \(v :: Vector P Word) (f :: Fun Word Int) -> V.smap (apply f) v !==! VP.map (apply f) (toPrimitiveVector v) prop "simap" $ \(v :: Vector P Word) (f :: Fun (Int, Word) Int) -> V.simap (applyFun2 f) v !==! VP.imap (applyFun2 f) (toPrimitiveVector v) prop "straverse" prop_straverse prop "sitraverse" prop_sitraverse prop "smapM" prop_smapM prop "simapM" prop_simapM prop "smapM" prop_smapM_ prop "simapM" prop_simapM_ prop "szip" prop_szip prop "szip3" prop_szip3 prop "szip4" prop_szip4 prop "szip5" prop_szip5 prop "szip6" prop_szip6 prop "szipWith" prop_szipWith prop "szipWith3" prop_szipWith3 prop "szipWith4" prop_szipWith4 prop "szipWith5" prop_szipWith5 prop "szipWith6" prop_szipWith6 prop "sizipWith" prop_sizipWith prop "sizipWith3" prop_sizipWith3 prop "sizipWith4" prop_sizipWith4 prop "sizipWith5" prop_sizipWith5 prop "sizipWith6" prop_sizipWith6 prop "liftA2" $ \(v1 :: Vector DS Word) (v2 :: Vector DS Int) (f :: Fun (Word, Int) Int) -> liftA2 (applyFun2 f) v1 v2 !==! toPrimV2 (VP.zipWith (applyFun2 f)) (compute v1) (compute v2) prop "szipWithM" prop_szipWithM prop "szipWith3M" prop_szipWith3M prop "szipWith4M" prop_szipWith4M prop "szipWith5M" prop_szipWith5M prop "szipWith6M" prop_szipWith6M prop "sizipWithM" prop_sizipWithM prop "sizipWith3M" prop_sizipWith3M prop "sizipWith4M" prop_sizipWith4M prop "sizipWith5M" prop_sizipWith5M prop "sizipWith6M" prop_sizipWith6M prop "szipWithM_" prop_szipWithM_ prop "szipWith3M_" prop_szipWith3M_ prop "szipWith4M_" prop_szipWith4M_ prop "szipWith5M_" prop_szipWith5M_ prop "szipWith6M_" prop_szipWith6M_ prop "sizipWithM_" prop_sizipWithM_ prop "sizipWith3M_" prop_sizipWith3M_ prop "sizipWith4M_" prop_sizipWith4M_ prop "sizipWith5M_" prop_sizipWith5M_ prop "sizipWith6M_" prop_sizipWith6M_ describe "Folding" $ do prop "sfoldl" $ \(v :: Vector P Word32) (f :: Fun (Word, Word32) Word) a0 -> V.sfoldl (applyFun2 f) a0 v === VP.foldl (applyFun2 f) a0 (toPrimitiveVector v) prop "sifoldl" $ \(v :: Vector P Word32) (f :: Fun (Word, Ix1, Word32) Word) a0 -> V.sifoldl (applyFun3 f) a0 v === VP.ifoldl (applyFun3 f) a0 (toPrimitiveVector v) prop "sfoldl1'" prop_sfoldl1' describe "Specialized" $ do prop "sor" $ \(v :: Vector S Bool) -> V.sor v === VS.or (toStorableVector v) prop "sand" $ \(v :: Vector S Bool) -> V.sand v === VS.and (toStorableVector v) prop "sany" $ \(v :: Vector P Word) (f :: Fun Word Bool) -> V.sany (apply f) v === VP.any (apply f) (toPrimitiveVector v) prop "sall" $ \(v :: Vector P Word) (f :: Fun Word Bool) -> V.sall (apply f) v === VP.all (apply f) (toPrimitiveVector v) prop "ssum" $ \(v :: Vector P Word) -> V.ssum v === VP.sum (toPrimitiveVector v) prop "sproduct" $ \(v :: Vector P Word) -> V.sproduct v === VP.product (toPrimitiveVector v) prop "maximum'" prop_maximum' prop "minimum'" prop_minimum' prop "maximumM" prop_maximumM prop "minimumM" prop_minimumM describe "Conversion" $ describe "Lists" $ do prop "sfromList" $ \comp (xs :: [Word]) -> sfromList xs !==! toPrimitiveVector (fromList comp xs) prop "sfromList" $ \(xs :: [Word]) -> sfromList xs !==! VP.fromList xs prop "sfromListN" $ \sz@(Sz n) (xs :: [Word]) -> sfromListN sz xs !==! VP.fromListN n xs prop "sfromListN (maxBound)" $ \(xs :: [Word]) -> sfromListN (Sz (maxBound `div` 8)) xs !==! VP.fromList xs prop "unsafeFromListN" $ \sz@(Sz n) (xs :: [Word]) -> A.unsafeFromListN sz xs !==! VP.fromListN n xs prop_sfoldl1' :: Vector P Word -> Fun (Word, Word) Word -> Property prop_sfoldl1' v f = V.singleton @D (V.sfoldl1' (applyFun2 f) v) !!==!! VP.singleton (VP.foldl1' (applyFun2 f) (toPrimitiveVector v)) prop_maximum' :: Vector P Word -> Property prop_maximum' v = V.singleton @D (V.smaximum' v) !!==!! VP.singleton (VP.maximum (toPrimitiveVector v)) prop_minimum' :: Vector P Word -> Property prop_minimum' v = V.singleton @D (V.sminimum' v) !!==!! VP.singleton (VP.minimum (toPrimitiveVector v)) prop_maximumM :: Vector P Word -> Property prop_maximumM v = let vp = toPrimitiveVector v in V.smaximumM v === (guard (not (VP.null vp)) >> Just (VP.maximum vp)) prop_minimumM :: Vector P Word -> Property prop_minimumM v = let vp = toPrimitiveVector v in V.sminimumM v === (guard (not (VP.null vp)) >> Just (VP.minimum vp)) prop_sitraverse_itraverseA :: SeedVector -> Vector S Word -> Property prop_sitraverse_itraverseA seed a = withSeed2 @(V.Vector P Word) seed (fmap compute . genWithIMapM (`V.sitraverse` a)) (genWithIMapM (`itraverseA` a)) prop_straverse_traversePrim :: SeedVector -> Vector S Word -> Property prop_straverse_traversePrim seed a = withSeed2 @(V.Vector P Word) seed (fmap compute . genWithIMapM (\f -> V.straverse (f 0) a)) (genWithIMapM (\f -> traversePrim (f 0) a)) prop_sitraverse_itraversePrim :: SeedVector -> Array P Ix3 Word -> Property prop_sitraverse_itraversePrim seed a = withSeed2 @(V.Vector P Word) seed (genWithIMapM (\f -> compute <$> V.sitraverse (xorToLinear f) a)) (genWithIMapM (\f -> flatten <$> itraversePrim @P (xorToLinear f) a)) where xorToLinear f i = f (foldlIndex xor 0 i) prop_smapM_traverseA_ :: SeedVector -> Array P Ix2 Word -> Property prop_smapM_traverseA_ seed a = withSeed seed (genWithMapM_ (`V.smapM_` a)) === withSeed seed (genWithMapM_ (`traverseA_` a)) prop_simapM_itraverseA_ :: SeedVector -> Array P Ix2 Word -> Property prop_simapM_itraverseA_ seed a = withSeed2 seed (genWithIMapM_ (\f -> V.simapM_ (xorToLinear f) a)) (genWithIMapM_ (\f -> itraverseA_ (xorToLinear f) a)) where xorToLinear f i = f (foldlIndex xor 0 i) prop_sforM_forM :: SeedVector -> Vector S Word -> Property prop_sforM_forM seed a = withSeed @(V.Vector P Word) seed (fmap compute . genWithMapM (V.sforM a)) === withSeed seed (genWithMapM (A.forM a)) prop_siforM_iforM :: SeedVector -> Vector S Word -> Property prop_siforM_iforM seed a = withSeed @(V.Vector P Word) seed (fmap compute . genWithIMapM (V.siforM a)) === withSeed seed (genWithIMapM (iforM a)) withSeedIO :: forall a. SeedVector -> (MWC.Gen (PrimState IO) -> IO a) -> IO a withSeedIO (SeedVector seed) f = MWC.initialize seed >>= f prop_sforM_forIO :: SeedVector -> Vector S Word -> Property prop_sforM_forIO seed a = property $ withSeedIO seed (genWithMapM (forIO (setComp Seq a))) `shouldReturn` withSeed @(V.Vector P Word) seed (fmap compute . genWithMapM (V.sforM a)) prop_siforM_iforIO :: SeedVector -> Vector S Word -> Property prop_siforM_iforIO seed a = property $ withSeedIO seed (genWithIMapM (iforIO (setComp (ParN 1) a))) `shouldReturn` withSeed @(V.Vector P Word) seed (fmap compute . genWithIMapM (V.siforM a)) prop_sforM_forM_ :: SeedVector -> Vector S Word -> Property prop_sforM_forM_ seed a = property $ withSeed seed (genWithMapM_ (A.forM_ a)) `shouldBe` withSeed @Word seed (genWithMapM_ (V.sforM_ a)) prop_siforM_iforM_ :: SeedVector -> Vector S Word -> Property prop_siforM_iforM_ seed a = property $ withSeed seed (genWithIMapM_ (iforM_ a)) `shouldBe` withSeed @Word seed (genWithIMapM_ (V.siforM_ a)) prop_sforM_forIO_ :: SeedVector -> Vector S Word -> Property prop_sforM_forIO_ seed a = property $ withSeedIO seed (genWithMapM_ (forIO_ (setComp (ParN 1) a))) `shouldReturn` withSeed @Word seed (genWithMapM_ (V.sforM_ a)) prop_siforM_iforIO_ :: SeedVector -> Vector S Word -> Property prop_siforM_iforIO_ seed a = property $ withSeedIO seed (genWithIMapM_ (iforIO_ (setComp (ParN 1) a))) `shouldReturn` withSeed @Word seed (genWithIMapM_ (V.siforM_ a)) prop_siforM_iforWS :: SeedVector -> Vector S Word -> Property prop_siforM_iforWS seed@(SeedVector sv) a = property $ do wsArray <- do ws <- initWorkerStates (ParN 1) (const (MWC.initialize sv)) genWithIMapWS (iforWS ws a) wsArray `shouldBe` withSeed @(V.Vector P Word) seed (fmap compute . genWithIMapM (V.siforM a)) prop_smapM_mapWS :: SeedVector -> Vector S Word -> Property prop_smapM_mapWS seed@(SeedVector sv) a = property $ do wsArray <- do ws <- initWorkerStates Seq (const (MWC.initialize sv)) genWithMapWS (\f -> mapWS ws f a) wsArray `shouldBe` withSeed @(V.Vector P Word) seed (fmap compute . genWithMapM (`V.smapM` a))