-- |
-- Copyright: (c) 2022 Bodigrim
-- Licence: BSD3
{-# LANGUAGE PostfixOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Use <$>" #-}
{-# HLINT ignore "Monad law, left identity" #-}
{-# HLINT ignore "Monad law, right identity" #-}
module Main where
import Test.QuickCheck.Function
import Test.Tasty
import Test.Tasty.QuickCheck as QC
import Control.Applicative
import Control.Monad
import Data.Bifunctor
import qualified Data.List as L
import Data.List.Infinite (Infinite(..))
import qualified Data.List.Infinite as I
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NE
import Data.Maybe
import Numeric.Natural
instance Arbitrary a => Arbitrary (Infinite a) where
arbitrary = (:<) <$> arbitrary <*> arbitrary
shrink = const []
instance Arbitrary a => Arbitrary (NonEmpty a) where
arbitrary = (:|) <$> arbitrary <*> arbitrary
trim :: Infinite a -> [a]
trim = I.take 10
trim1 :: Infinite a -> [a]
trim1 = I.take 11
mapMapFusion :: Infinite Int -> Infinite Int
mapMapFusion xs = I.map fromIntegral (I.map fromIntegral xs :: Infinite Word)
main :: IO ()
main = defaultMain $ testGroup "All"
[ testProperty "head" $
\(Blind (xs :: Infinite Int)) ->
I.head xs == L.head (trim xs)
, testProperty "tail" $
\(Blind (xs :: Infinite Int)) ->
trim (I.tail xs) == L.tail (trim1 xs)
, testProperty "uncons" $
\(Blind (xs :: Infinite Int)) ->
Just (fmap trim (I.uncons xs)) == L.uncons (trim1 xs)
, testProperty "map" $
\(applyFun -> f :: Int -> Word) (Blind (xs :: Infinite Int)) ->
trim (I.map f xs) == L.map f (trim xs)
, testProperty "fmap" $
\(applyFun -> f :: Int -> Int) (Blind (xs :: Infinite Int)) ->
trim (fmap f xs) == fmap f (trim xs)
, testProperty "<$" $
\(x :: Word) (Blind (xs :: Infinite Int)) ->
trim (x <$ xs) == trim (fmap (const x) xs)
, testProperty "pure" $
\(applyFun -> f :: Int -> Word) (x :: Int) ->
trim (pure f <*> pure x) == trim (pure (f x))
, testProperty "*>" $
\(Blind (xs :: Infinite Int)) (Blind (ys :: Infinite Word)) ->
trim (xs *> ys) == trim ((id <$ xs) <*> ys)
, testProperty "<*" $
\(Blind (xs :: Infinite Int)) (Blind (ys :: Infinite Word)) ->
trim (xs <* ys) == trim (liftA2 const xs ys)
, testProperty ">>= 1" $
\x ((I.cycle .) . applyFun -> k :: Int -> Infinite Word) ->
trim (return x >>= k) == trim (k x)
, testProperty ">>= 2" $
\(Blind (xs :: Infinite Int)) ->
trim (xs >>= return) == trim xs
, testProperty ">>= 3" $
\(Blind xs) ((I.cycle .) . applyFun -> k :: Int -> Infinite Word) ((I.cycle .) . applyFun -> h :: Word -> Infinite Char) ->
trim (xs >>= (k >=> h)) == trim ((xs >>= k) >>= h)
, testProperty ">>" $
\(Blind (xs :: Infinite Int)) (Blind (ys :: Infinite Word)) ->
trim (xs >> ys) == trim ys
, testProperty "concat" $
\(Blind (xs :: Infinite (NonEmpty Int))) ->
trim (I.concat xs) == L.take 10 (L.concatMap NE.toList (I.toList xs))
, testProperty "concatMap" $
\(applyFun -> f :: Int -> NonEmpty Word) (Blind xs) ->
trim (I.concatMap f xs) == L.take 10 (L.concatMap (NE.toList . f) (I.toList xs))
, testProperty "intersperse" $
\(x :: Int) (Blind xs) ->
I.take 19 (I.intersperse x xs) == L.intersperse x (trim xs)
, testProperty "intersperse laziness 1" $
I.head (I.intersperse undefined ('q' :< undefined)) == 'q'
, testProperty "intersperse laziness 2" $
I.take 2 (I.intersperse 'w' ('q' :< undefined)) == "qw"
, testProperty "intercalate" $
\(x :: NonEmpty Int) (Blind xs) ->
I.take (sum (map length (trim xs)) + 9 * length x) (I.intercalate x xs) == L.intercalate (NE.toList x) (trim xs)
, testProperty "intercalate laziness 1" $
I.take 3 (I.intercalate undefined ("foo" :< undefined)) == "foo"
, testProperty "intercalate laziness 2" $
I.take 6 (I.intercalate (NE.fromList "bar") ("foo" :< undefined)) == "foobar"
, testProperty "interleave 1" $
\(Blind (xs :: Infinite Int)) (Blind ys) ->
trim (I.map snd (I.filter fst (I.zip (I.cycle (True :| [False])) (I.interleave xs ys)))) == trim xs
, testProperty "interleave 2" $
\(Blind (xs :: Infinite Int)) (Blind ys) ->
trim (I.map snd (I.filter fst (I.zip (I.cycle (False :| [True])) (I.interleave xs ys)))) == trim ys
, testProperty "interleave laziness" $
I.head (I.interleave ('a' :< undefined) undefined) == 'a'
, testProperty "transpose []" $
\(fmap getBlind -> xss :: [Infinite Int]) -> not (null xss) ==>
trim (I.transpose xss) == L.transpose (map trim xss)
, testProperty "transpose NE" $
\(fmap getBlind -> xss :: NonEmpty (Infinite Int)) ->
NE.fromList (trim (I.transpose xss)) == NE.transpose (NE.map (NE.fromList . trim) xss)
, testProperty "transpose laziness 1" $
I.head (I.transpose ['a' :< undefined, 'b' :< undefined]) == "ab"
, testProperty "transpose laziness 2" $
I.head (I.transpose (('a' :< undefined) :| ['b' :< undefined])) == 'a' :| "b"
, testProperty "subsequences" $
\(Blind (xs :: Infinite Int)) ->
I.take 16 (I.subsequences xs) == L.subsequences (I.take 4 xs)
, testProperty "subsequences laziness 1" $
I.head (I.subsequences undefined) == ""
, testProperty "subsequences laziness 2" $
I.take 2 (I.subsequences ('q' :< undefined)) == ["", "q"]
, testProperty "permutations" $
\(Blind (xs :: Infinite Int)) ->
map (I.take 4) (I.take 24 (I.permutations xs)) == L.permutations (I.take 4 xs)
, testProperty "permutations laziness" $
I.take 6 (I.map (I.take 3) (I.permutations ('q' :< 'w' :< 'e' :< undefined))) == ["qwe","wqe","ewq","weq","eqw","qew"]
, testProperty "... Bool" $
\(x :: Bool) ->
trim (x I....) === L.take 10 (L.cycle [x..])
, testProperty "... Int" $
\(x :: Int) ->
trim (x I....) == L.take 10 (L.cycle [x..])
, testProperty "... Int maxBound" $
\(NonNegative (x' :: Int)) -> let x = maxBound - x' in
trim (x I....) == L.take 10 (L.cycle [x..])
, testProperty "... Word" $
\(x :: Word) ->
trim (x I....) == L.take 10 (L.cycle [x..])
, testProperty "... Word maxBound" $
\(NonNegative (x' :: Word)) -> let x = maxBound - x' in
trim (x I....) == L.take 10 (L.cycle [x..])
, testProperty "... Integer" $
\(x :: Integer) ->
trim (x I....) == L.take 10 (L.cycle [x..])
, testProperty "... Natural" $
\(NonNegative (x' :: Integer)) -> let x = fromInteger x' :: Natural in
trim (x I....) == L.take 10 (L.cycle [x..])
, testProperty ".... Bool" $
\(x :: Bool) y ->
trim ((x, y) I.....) == L.take 10 (L.cycle [x, y..])
, testProperty ".... Int" $
\(x :: Int) y ->
trim ((x, y) I.....) == L.take 10 (L.cycle [x, y..]) .&&.
trim ((maxBound + x, y) I.....) == L.take 10 (L.cycle [maxBound + x, y..]) &&
trim ((x, maxBound + y) I.....) == L.take 10 (L.cycle [x, maxBound + y..]) &&
trim ((maxBound + x, maxBound + y) I.....) == L.take 10 (L.cycle [maxBound + x, maxBound + y..])
, testProperty ".... Word" $
\(x :: Word) y ->
trim ((x, y) I.....) == L.take 10 (L.cycle [x, y..]) .&&.
trim ((maxBound + x, y) I.....) == L.take 10 (L.cycle [maxBound + x, y..]) &&
trim ((x, maxBound + y) I.....) == L.take 10 (L.cycle [x, maxBound + y..]) &&
trim ((maxBound + x, maxBound + y) I.....) == L.take 10 (L.cycle [maxBound + x, maxBound + y..])
, testProperty ".... Integer" $
\(x :: Integer) y ->
trim ((x, y) I.....) == L.take 10 (L.cycle [x, y..])
, testProperty ".... Natural" $
\(NonNegative (x' :: Integer)) (NonNegative (y' :: Integer)) ->
let x = fromInteger x' :: Natural in let y = fromInteger y' in
trim ((x, y) I.....) == L.take 10 (L.cycle [x, y..])
, testProperty "toList" $
\(Blind (xs :: Infinite Int)) ->
L.take 10 (I.toList xs) == trim xs
, testProperty "scanl" $
\(curry . applyFun -> f :: Word -> Int -> Word) s (Blind xs) ->
trim1 (I.scanl f s xs) == L.scanl f s (trim xs)
, testProperty "scanl laziness" $
I.head (I.scanl undefined 'q' undefined) == 'q'
, testProperty "scanl'" $
\(curry . applyFun -> f :: Word -> Int -> Word) s (Blind xs) ->
trim1 (I.scanl' f s xs) == L.scanl' f s (trim xs)
, testProperty "scanl' laziness" $
I.head (I.scanl' undefined 'q' undefined) == 'q'
, testProperty "scanl1" $
\(curry . applyFun -> f :: Int -> Int -> Int) (Blind xs) ->
trim (I.scanl1 f xs) == L.scanl1 f (trim xs)
, testProperty "scanl1 laziness" $
I.head (I.scanl1 undefined ('q' :< undefined)) == 'q'
, testProperty "mapAccumL" $
\(curry . applyFun -> f :: Bool -> Int -> (Bool, Word)) (Blind xs) ->
trim (I.mapAccumL f False xs) == snd (L.mapAccumL f False (trim xs))
, testProperty "mapAccumL laziness" $
I.head (I.mapAccumL (\_ x -> (undefined, x)) undefined ('q' :< undefined)) == 'q'
, testProperty "iterate" $
\(applyFun -> f :: Int -> Int) s ->
trim (I.iterate f s) == L.take 10 (L.iterate f s)
, testProperty "iterate laziness" $
I.head (I.iterate undefined 'q') == 'q'
, testProperty "iterate'" $
\(applyFun -> f :: Int -> Int) s ->
trim (I.iterate' f s) == L.take 10 (L.iterate f s)
, testProperty "iterate' laziness" $
I.head (I.iterate' undefined 'q') == 'q'
, testProperty "repeat" $
\(s :: Int) ->
trim (I.repeat s) == L.replicate 10 s
, testProperty "cycle" $
\(xs :: NonEmpty Int) ->
trim (I.cycle xs) == L.take 10 (L.cycle (NE.toList xs))
, testProperty "cycle laziness" $
I.head (I.cycle ('q' :| undefined)) == 'q'
, testProperty "unfoldr" $
\(applyFun -> f :: Word -> (Int, Word)) s ->
trim (I.unfoldr f s) == L.take 10 (L.unfoldr (Just . f) s)
, testProperty "unfoldr laziness" $
I.head (I.unfoldr (, undefined) 'q') == 'q'
, testProperty "take" $
\n (Blind (xs :: Infinite Int)) ->
L.take 10 (I.take n xs) == L.take n (trim xs)
, testProperty "take laziness 1" $
I.take 0 undefined == ""
, testProperty "take laziness 2" $
I.take 1 ('q' :< undefined) == "q"
, testProperty "drop" $
\n (Blind (xs :: Infinite Int)) ->
trim (I.drop n xs) == L.drop n (I.take (max n 0 + 10) xs)
, testProperty "splitAt" $
\n (Blind (xs :: Infinite Int)) ->
bimap (L.take 10) trim (I.splitAt n xs) ==
first (L.take 10) (L.splitAt n (I.take (max n 0 + 10) xs))
, testProperty "splitAt laziness 1" $
fst (I.splitAt 0 undefined) == ""
, testProperty "splitAt laziness 2" $
fst (I.splitAt 1 ('q' :< undefined)) == "q"
, testProperty "takeWhile" $
\(applyFun -> f :: Ordering -> Bool) (Blind xs) ->
let ys = L.take 10 (I.takeWhile f xs) in
L.take 10 (L.takeWhile f (I.take (length ys + 10) xs)) ==
L.take 10 (I.takeWhile f xs)
, testProperty "takeWhile laziness 1" $
L.null (I.takeWhile (const False) ('q' :< undefined))
, testProperty "takeWhile laziness 2" $
L.head (I.takeWhile (const True) ('q' :< undefined)) == 'q'
, testProperty "fst . span" $
\(applyFun -> f :: Ordering -> Bool) (Blind xs) ->
let ys = L.take 10 (fst (I.span f xs)) in
L.take 10 (L.takeWhile f (I.take (length ys + 10) xs)) ==
L.take 10 (fst (I.span f xs))
, testProperty "fst . break" $
\(applyFun -> f :: Ordering -> Bool) (Blind xs) ->
let ys = L.take 10 (fst (I.break f xs)) in
L.take 10 (L.takeWhile (not . f) (I.take (length ys + 10) xs)) ==
L.take 10 (fst (I.break f xs))
, testProperty "dropWhile" $
\(applyFun -> f :: Ordering -> Bool) (Blind xs) ->
trim (L.foldr (:<) (I.dropWhile f xs) (I.takeWhile f xs)) == trim xs
, testProperty "snd . span" $
\(applyFun -> f :: Ordering -> Bool) (Blind xs) ->
trim (L.foldr (:<) (snd (I.span f xs)) (I.takeWhile f xs)) == trim xs
, testProperty "snd . break" $
\(applyFun -> f :: Ordering -> Bool) (Blind xs) ->
trim (L.foldr (:<) (snd (I.break f xs)) (I.takeWhile (not . f) xs)) == trim xs
, testProperty "span laziness" $
L.head (fst (I.span (/= '\n') ('q' :< undefined))) == 'q'
, testProperty "break laziness" $
L.head (fst (I.break (== '\n') ('q' :< undefined))) == 'q'
, testProperty "stripPrefix" $
\(xs :: [Int]) (Blind (ys :: Infinite Int)) ->
fmap trim (I.stripPrefix xs ys) == fmap (L.take 10) (L.stripPrefix xs (I.take (length xs + 10) ys))
, testProperty "stripPrefix laziness 1" $
isNothing (I.stripPrefix ('q' : undefined) ('w' :< undefined))
, testProperty "stripPrefix laziness 2" $
isJust (I.stripPrefix "foo" ('f' :< 'o' :< 'o' :< undefined))
, testProperty "isPrefixOf" $
\(xs :: [Int]) (Blind (ys :: Infinite Int)) ->
I.isPrefixOf xs ys == L.isPrefixOf xs (I.take (length xs + 10) ys)
, testProperty "isPrefixOf laziness 1" $
not (I.isPrefixOf ('q' : undefined) ('w' :< undefined))
, testProperty "isPrefixOf laziness 2" $
I.isPrefixOf "foo" ('f' :< 'o' :< 'o' :< undefined)
, testProperty "zip" $
\(Blind (xs1 :: Infinite Int)) (Blind (xs2 :: Infinite Word)) ->
trim (I.zip xs1 xs2) == L.zip (trim xs1) (trim xs2)
, testProperty "zip3" $
\(Blind (xs1 :: Infinite Int)) (Blind (xs2 :: Infinite Word)) (Blind (xs3 :: Infinite Bool)) ->
trim (I.zip3 xs1 xs2 xs3) == L.zip3 (trim xs1) (trim xs2) (trim xs3)
, testProperty "zip4" $
\(Blind (xs1 :: Infinite Int)) (Blind (xs2 :: Infinite Word)) (Blind (xs3 :: Infinite Bool)) (Blind (xs4 :: Infinite Char)) ->
trim (I.zip4 xs1 xs2 xs3 xs4) == L.zip4 (trim xs1) (trim xs2) (trim xs3) (trim xs4)
, testProperty "zip5" $
\(Blind (xs1 :: Infinite Int)) (Blind (xs2 :: Infinite Word)) (Blind (xs3 :: Infinite Bool)) (Blind (xs4 :: Infinite Char)) (Blind (xs5 :: Infinite Ordering)) ->
trim (I.zip5 xs1 xs2 xs3 xs4 xs5) == L.zip5 (trim xs1) (trim xs2) (trim xs3) (trim xs4) (trim xs5)
, testProperty "zip6" $
\(Blind (xs1 :: Infinite Int)) (Blind (xs2 :: Infinite Word)) (Blind (xs3 :: Infinite Bool)) (Blind (xs4 :: Infinite Char)) (Blind (xs5 :: Infinite Ordering)) (Blind (xs6 :: Infinite String)) ->
trim (I.zip6 xs1 xs2 xs3 xs4 xs5 xs6) == L.zip6 (trim xs1) (trim xs2) (trim xs3) (trim xs4) (trim xs5) (trim xs6)
, testProperty "zip7" $
\(Blind (xs1 :: Infinite Int)) (Blind (xs2 :: Infinite Word)) (Blind (xs3 :: Infinite Bool)) (Blind (xs4 :: Infinite Char)) (Blind (xs5 :: Infinite Ordering)) (Blind (xs6 :: Infinite String)) (Blind (xs7 :: Infinite Integer)) ->
trim (I.zip7 xs1 xs2 xs3 xs4 xs5 xs6 xs7) == L.zip7 (trim xs1) (trim xs2) (trim xs3) (trim xs4) (trim xs5) (trim xs6) (trim xs7)
, testProperty "unzip" $
\(Blind (xs :: Infinite (Int, Word))) ->
bimap trim trim (I.unzip xs) == L.unzip (trim xs)
, testProperty "unzip3" $
\(Blind (xs :: Infinite (Int, Word, Bool))) ->
(\(xs1, xs2, xs3) -> (trim xs1, trim xs2, trim xs3)) (I.unzip3 xs) == L.unzip3 (trim xs)
, testProperty "unzip4" $
\(Blind (xs :: Infinite (Int, Word, Bool, Char))) ->
(\(xs1, xs2, xs3, xs4) -> (trim xs1, trim xs2, trim xs3, trim xs4)) (I.unzip4 xs) == L.unzip4 (trim xs)
, testProperty "unzip5" $
\(Blind (xs :: Infinite (Int, Word, Bool, Char, Ordering))) ->
(\(xs1, xs2, xs3, xs4, xs5) -> (trim xs1, trim xs2, trim xs3, trim xs4, trim xs5)) (I.unzip5 xs) == L.unzip5 (trim xs)
, testProperty "unzip6" $
\(Blind (xs :: Infinite (Int, Word, Bool, Char, Ordering, String))) ->
(\(xs1, xs2, xs3, xs4, xs5, xs6) -> (trim xs1, trim xs2, trim xs3, trim xs4, trim xs5, trim xs6)) (I.unzip6 xs) == L.unzip6 (trim xs)
, testProperty "unzip7" $
\(Blind (xs :: Infinite (Int, Word, Bool, Char, Ordering, String, Integer))) ->
(\(xs1, xs2, xs3, xs4, xs5, xs6, xs7) -> (trim xs1, trim xs2, trim xs3, trim xs4, trim xs5, trim xs6, trim xs7)) (I.unzip7 xs) == L.unzip7 (trim xs)
, testProperty "lines" $
\(Blind (xs :: Infinite Char)) ->
I.take 3 (I.lines xs) == L.take 3 (L.lines (I.foldr (:) xs))
, testProperty "lines laziness 1" $
L.head (I.head (I.lines ('q' :< undefined))) == 'q'
, testProperty "lines laziness 2" $
L.null (I.head (I.lines ('\n' :< undefined)))
, testProperty "words" $
\(Blind (xs :: Infinite Char)) ->
I.take 3 (I.map NE.toList (I.words xs)) == L.take 3 (L.words (I.foldr (:) xs))
, testProperty "words laziness" $
NE.head (I.head (I.words ('q' :< undefined))) == 'q'
, testProperty "unlines" $
\(Blind (xs :: Infinite [Char])) ->
trim (I.unlines xs) == L.take 10 (L.unlines (trim xs))
, testProperty "unlines laziness" $
I.take 2 (I.unlines ("q" :< undefined)) == "q\n"
, testProperty "unwords" $
\(Blind (xs :: Infinite (NonEmpty Char))) ->
trim (I.unwords xs) == L.take 10 (L.unwords (L.map NE.toList (trim xs)))
, testProperty "unwords laziness" $
I.take 2 (I.unwords (('q' :| []) :< undefined)) == "q "
, testProperty "group" $
\(Blind (ys :: Infinite Ordering)) ->
trim (I.group ys) == L.take 10 (NE.group (I.foldr (:) ys))
, testProperty "group laziness" $
NE.head (I.head (I.group ('q' :< undefined))) == 'q'
, testProperty "nub" $
\(Blind (ys :: Infinite (Large Int))) ->
I.take 3 (I.nub ys) == L.take 3 (L.nub (I.foldr (:) ys))
, testProperty "nub laziness" $
I.head (I.nub ('q' :< undefined)) == 'q'
, testProperty "delete" $
\(x :: Ordering) (Blind xs) ->
trim (I.delete x xs) == L.take 10 (L.delete x (I.foldr (:) xs))
, testProperty "delete laziness" $
I.head (I.delete 'q' ('w' :< undefined)) == 'w'
, testProperty "insert" $
\(x :: Int) (Blind xs) ->
trim (I.insert x xs) == L.take 10 (L.insert x (I.foldr (:) xs))
, testProperty "insert laziness" $
I.take 2 (I.insert 'q' ('w' :< undefined)) == "qw"
, testProperty "\\\\" $
\(Blind (xs :: Infinite Ordering)) ys ->
trim (xs I.\\ ys) == L.take 10 (I.foldr (:) xs L.\\ ys)
, testProperty "\\\\ laziness" $
I.head (('q' :< undefined) I.\\ []) == 'q'
, testProperty "union" $
\xs (Blind (ys :: Infinite Ordering)) ->
I.take 3 (I.union xs ys) == L.take 3 (xs `L.union` I.foldr (:) ys)
, testProperty "union laziness" $
I.head (I.union ('q' : undefined) undefined) == 'q'
, testProperty "intersect" $
\(Blind (xs :: Infinite Ordering)) ys -> not (null ys) ==>
I.head (I.intersect xs ys) == L.head (I.foldr (:) xs `L.intersect` ys)
, testProperty "intersect laziness" $
I.head (I.intersect ('q' :< undefined) ('q' : undefined)) == 'q'
, testProperty "inits" $
\(Blind (xs :: Infinite Int)) ->
I.take 21 (I.inits xs) == L.inits (I.take 20 xs)
, testProperty "inits laziness 1" $
L.null (I.head (I.inits undefined))
, testProperty "inits laziness 2" $
I.take 2 (I.inits ('q' :< undefined)) == ["", "q"]
, testProperty "inits1" $
\(Blind (xs :: Infinite Int)) ->
map NE.toList (trim (I.inits1 xs)) == L.tail (L.inits (trim xs))
, testProperty "tails" $
\(Blind (xs :: Infinite Int)) ->
map trim (trim (I.tails xs)) === map (L.take 10) (L.take 10 (L.tails (I.take 20 xs)))
, testProperty "tails laziness" $
I.head (I.head (I.tails ('q' :< undefined))) == 'q'
, testProperty "lookup" $
\(xs :: [(Int, Word)]) y zs ->
let pairs = NE.fromList (xs ++ (y : zs)) in
Just (I.lookup (fst y) (I.cycle pairs)) == L.lookup (fst y) (NE.toList pairs)
, testProperty "lookup laziness" $
I.lookup True ((True, 'q') :< undefined) == 'q'
, testProperty "find" $
\(xs :: [(Int, Word)]) y zs ->
let pairs = NE.fromList (xs ++ (y : zs)) in
Just (I.find ((== snd y) . snd) (I.cycle pairs)) == L.find ((== snd y) . snd) (NE.toList pairs)
, testProperty "find laziness" $
I.find odd (1 :< undefined) == (1 :: Int)
, testProperty "filter" $
\(applyFun -> f :: Int -> Bool) xs (Blind ys) ->
let us = L.filter f xs in
us == I.take (length us) (I.filter f (I.prependList xs ys))
, testProperty "partition" $
\(applyFun -> f :: Int -> Bool) xs (Blind ys) ->
let (us, vs) = L.partition f xs in
let (us', vs') = I.partition f (I.prependList xs ys) in
us == I.take (length us) us' && vs == I.take (length vs) vs'
, testProperty "!!" $
\(Blind (xs :: Infinite Int)) n ->
xs I.!! n == I.foldr (:) xs L.!! fromIntegral n
, testProperty "tabulate" $
\(applyFun -> f :: Word -> Char) n ->
I.tabulate f I.!! n == f n
, testProperty "elemIndex" $
\xs (x :: Int) (Blind ys) ->
let zs = I.prependList xs (x :< ys) in
Just (fromIntegral (I.elemIndex x zs)) == L.elemIndex x (I.foldr (:) zs)
, testProperty "elemIndices" $
\xs (x :: Ordering) (Blind ys) ->
let zs = I.prependList xs (x :< ys) in
let is = L.elemIndices x (xs ++ [x]) in
map fromIntegral (I.take (length is) (I.elemIndices x zs)) == is
]