1{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
3module Main (main) where
6import Data.Semigroup (Sum(..), getSum)
7import Streamly.Test.Common (checkListEqual, listEquals)
21import Control.Monad.IO.Class (liftIO)
22import Test.QuickCheck.Monadic (monadicIO, assert, run)
24import qualified Data.Map
25import qualified Prelude
26import qualified Streamly.Internal.Data.Array.Mut as MArray
27import qualified Streamly.Internal.Data.Fold as Fold
28import qualified Streamly.Internal.Data.Fold.Container as Fold
29import qualified Streamly.Internal.Data.Stream as Stream
32 (maximum, minimum, elem, notElem, null, product, sum, head, last, take)
34import Test.Hspec.QuickCheck
51chooseInt :: (Int, Int) -> Gen Int
54{-# INLINE maxStreamLen #-}
58rollingHashFirstN :: Property
60 forAll (choose (0, maxStreamLen)) $ \len ->
61 forAll (choose (0, len)) $ \n ->
62 forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec ->
65 $ Stream.fold Fold.rollingHash
69 $ Stream.fold (Fold.rollingHashFirstN n)
73head :: [Int] -> Expectation
74head ls = Stream.fold Fold.one (Stream.fromList ls) `shouldReturn` headl ls
76headl :: [a] -> Maybe a
80length :: [Int] -> Expectation
81length ls = Stream.fold Fold.length (Stream.fromList ls) `shouldReturn` Prelude.length ls
83sum :: [Int] -> Expectation
84sum ls = Stream.fold Fold.sum (Stream.fromList ls) `shouldReturn` Prelude.sum ls
86product :: [Int] -> Expectation
88 Stream.fold Fold.product (Stream.fromList ls) `shouldReturn` Prelude.product ls
90lesser :: (a -> a -> Ordering) -> a -> a -> a
91lesser f x y = if f x y == LT then x else y
93greater :: (a -> a -> Ordering) -> a -> a -> a
94greater f x y = if f x y == GT then x else y
96foldMaybe :: (b -> a -> b) -> b -> [a] -> Maybe b
100 _ -> Just (foldl f acc ls)
102maximumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
103maximumBy genmin f ls =
104 Stream.fold (Fold.maximumBy f) (Stream.fromList ls)
105 `shouldReturn` foldMaybe (greater f) genmin ls
107maximum :: (Show a, Ord a) => a -> [a] -> Expectation
109 Stream.fold Fold.maximum (Stream.fromList ls)
110 `shouldReturn` foldMaybe (greater compare) genmin ls
112minimumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
113minimumBy genmax f ls =
114 Stream.fold (Fold.minimumBy f) (Stream.fromList ls)
115 `shouldReturn` foldMaybe (lesser f) genmax ls
117minimum :: (Show a, Ord a) => a -> [a] -> Expectation
119 Stream.fold Fold.minimum (Stream.fromList ls)
120 `shouldReturn` foldMaybe (lesser compare) genmax ls
122toList :: [Int] -> Expectation
123toList ls = Stream.fold Fold.toList (Stream.fromList ls) `shouldReturn` ls
125toListRev :: [Int] -> Expectation
126toListRev ls = Stream.fold Fold.toListRev (Stream.fromList ls) `shouldReturn` reverse ls
128safeLast :: [a] -> Maybe a
130safeLast (x:[]) = Just x
131safeLast (_:xs) = safeLast xs
133last :: [String] -> Expectation
134last ls = Stream.fold Fold.last (Stream.fromList ls) `shouldReturn` safeLast ls
136mapMaybe :: [Int] -> Expectation
142 f = Fold.mapMaybe maybeEven Fold.toList
143 in Stream.fold f (Stream.fromList ls) `shouldReturn` filter even ls
145nth :: Int -> [a] -> Maybe a
149 | otherwise = nth (idx - 1) xs
152index :: Int -> [String] -> Expectation
154 let x = Stream.fold (Fold.index idx) (Stream.fromList ls)
155 in x `shouldReturn` nth idx ls
157find :: (Show a, Eq a) => (a -> Bool) -> [a] -> Expectation
159 y <- Stream.fold (Fold.findIndex f) (Stream.fromList ls)
162 let fld = Stream.fold (Fold.find f) (Stream.fromList ls)
163 in fld `shouldReturn` Nothing
165 let fld = Stream.fold (Fold.any f) (Stream.fromList $ Prelude.take idx ls)
166 in fld `shouldReturn` False
168neg :: (a -> Bool) -> a -> Bool
171findIndex :: (a -> Bool) -> [a] -> Expectation
173 y <- Stream.fold (Fold.findIndex f) (Stream.fromList ls)
176 let fld = Stream.fold (Fold.all $ neg f) (Stream.fromList ls)
177 in fld `shouldReturn` True
181 Stream.fold (Fold.all f) (Stream.fromList []) `shouldReturn` True
183 Stream.fold (Fold.all f) (Stream.fromList $ Prelude.take idx ls)
186predicate :: Int -> Bool
187predicate x = x * x < 100
189elemIndex :: Int -> [Int] -> Expectation
191 y <- Stream.fold (Fold.elemIndex elm) (Stream.fromList ls)
194 let fld = Stream.fold (Fold.any (== elm)) (Stream.fromList ls)
195 in fld `shouldReturn` False
200 (Stream.fromList $ Prelude.take idx ls)
201 in fld `shouldReturn` False
203null :: [Int] -> Expectation
205 Stream.fold Fold.null (Stream.fromList ls)
211elem :: Int -> [Int] -> Expectation
213 y <- Stream.fold (Fold.elem elm) (Stream.fromList ls)
214 let fld = Stream.fold (Fold.any (== elm)) (Stream.fromList ls)
217notElem :: Int -> [Int] -> Expectation
219 y <- Stream.fold (Fold.notElem elm) (Stream.fromList ls)
220 let fld = Stream.fold (Fold.any (== elm)) (Stream.fromList ls)
221 fld `shouldReturn` not y
223all :: (a -> Bool) -> [a] -> Expectation
225 Stream.fold (Fold.all f) (Stream.fromList ls) `shouldReturn` Prelude.all f ls
227any :: (a -> Bool) -> [a] -> Expectation
228any f ls = Stream.fold (Fold.any f) (Stream.fromList ls) `shouldReturn` Prelude.any f ls
230and :: [Bool] -> Expectation
231and ls = Stream.fold Fold.and (Stream.fromList ls) `shouldReturn` Prelude.and ls
233or :: [Bool] -> Expectation
234or ls = Stream.fold Fold.or (Stream.fromList ls) `shouldReturn` Prelude.or ls
236take :: [Int] -> Property
238 forAll (chooseInt (-1, Prelude.length ls + 2)) $ \n ->
239 Stream.fold (Fold.take n Fold.toList) (Stream.fromList ls)
240 `shouldReturn` Prelude.take n ls
242takeEndBy_ :: Property
244 forAll (listOf (chooseInt (0, 1))) $ \ls ->
246 f = Fold.takeEndBy_ p Fold.toList
247 ys = Prelude.takeWhile (not . p) ls
248 in case Stream.fold f (Stream.fromList ls) of
249 Right xs -> checkListEqual xs ys
250 Left _ -> property False
252takeEndByOrMax :: Property
254 forAll (chooseInt (min_value, max_value)) $ \n ->
255 forAll (listOf (chooseInt (0, 1))) $ \ls ->
257 f = Fold.takeEndBy_ p (Fold.take n Fold.toList)
258 ys = Prelude.take n (Prelude.takeWhile (not . p) ls)
259 in case Stream.fold f (Stream.fromList ls) of
260 Right xs -> checkListEqual xs ys
261 Left _ -> property False
263chooseFloat :: (Float, Float) -> Gen Float
266drain :: [Int] -> Expectation
267drain ls = Stream.fold Fold.drain (Stream.fromList ls) `shouldReturn` ()
269drainBy :: [Int] -> Expectation
270drainBy ls = Stream.fold (Fold.drainBy return) (Stream.fromList ls) `shouldReturn` ()
274 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
275 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
280 v1 <- run $ Stream.fold Fold.mean (Stream.fromList ls)
281 let v2 = Prelude.sum ls / fromIntegral (Prelude.length ls)
282 assert (abs (v1 - v2) < 0.0001)
286 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
287 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
292 v1 <- run $ Stream.fold Fold.stdDev (Stream.fromList ls)
293 let avg = Prelude.sum ls / fromIntegral (Prelude.length ls)
294 se = Prelude.sum (fmap (\x -> (x - avg) * (x - avg)) ls)
295 sd = sqrt $ se / fromIntegral (Prelude.length ls)
296 assert (abs (v1 - sd) < 0.0001 )
300 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
301 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
306 v1 <- run $ Stream.fold Fold.variance (Stream.fromList ls)
307 let avg = Prelude.sum ls / fromIntegral (Prelude.length ls)
308 se = Prelude.sum (fmap (\x -> (x - avg) * (x - avg)) ls)
309 vr = se / fromIntegral (Prelude.length ls)
310 assert (abs (v1 - vr) < 0.01 )
314 forAll (listOf1 (chooseInt (intMin, intMax)))
315 $ \ls0 -> monadicIO $ action ls0
320 v1 <- run $ Stream.fold Fold.mconcat (fmap Sum $ Stream.fromList ls)
321 let v2 = Prelude.sum ls
322 assert (getSum v1 == v2)
326 forAll (listOf1 (chooseInt (intMin, intMax)))
327 $ \ls0 -> monadicIO $ action ls0
332 v1 <- run $ Stream.fold (Fold.foldMap Sum) $ Stream.fromList ls
333 let v2 = Prelude.sum ls
334 assert (getSum v1 == v2)
338 forAll (listOf1 (chooseInt (intMin, intMax)))
339 $ \ls0 -> monadicIO $ action ls0
344 v1 <- run $ Stream.fold (Fold.foldMapM (return . Sum)) $ Stream.fromList ls
345 let v2 = Prelude.sum ls
346 assert (getSum v1 == v2)
350 forAll (chooseInt (1, 15))
351 $ \key0 ->monadicIO $ action key0
356 let ls = [ (1, "first"), (2, "second"), (3, "third"), (4, "fourth")
357 , (5, "fifth"), (6, "fifth+first"), (7, "fifth+second")
358 , (8, "fifth+third"), (9, "fifth+fourth")
359 , (10, "fifth+fifth")
361 v1 <- run $ Stream.fold (Fold.lookup key) $ Stream.fromList ls
362 let v2 = Prelude.lookup key ls
367 forAll (listOf1 (chooseInt (intMin, intMax)))
368 $ \ls0 -> monadicIO $ action ls0
373 let addLen x = return $ x + Prelude.length ls
374 fld = Fold.rmapM addLen Fold.sum
375 v2 = foldl (+) (Prelude.length ls) ls
376 v1 <- run $ Stream.fold fld $ Stream.fromList ls
379teeWithLength :: Property
381 forAll (listOf1 (chooseInt (intMin, intMax)))
382 $ \ls0 -> monadicIO $ action ls0
387 v1 <- run $ Stream.fold (Fold.tee Fold.sum Fold.length) $ Stream.fromList ls
388 let v2 = Prelude.sum ls
389 v3 = Prelude.length ls
390 assert (v1 == (v2, v3))
392teeWithFstLength :: Property
394 forAll (listOf1 (chooseInt (intMin, intMax)))
395 $ \ls0 -> monadicIO $ action ls0
402 $ Stream.fold (Fold.teeWithFst (,) (Fold.take 5 Fold.sum) Fold.length)
404 let v2 = Prelude.sum (Prelude.take 5 ls)
405 v3 = Prelude.length (Prelude.take 5 ls)
406 assert (v1 == (v2, v3))
408partitionByM :: Property
410 forAll (listOf1 (chooseInt (intMin, intMax)))
411 $ \ls0 -> monadicIO $ action ls0
416 let f = \x -> if odd x then return (Left x) else return (Right x)
419 $ Stream.fold (Fold.partitionByM f Fold.length Fold.length)
421 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ls
422 v3 = foldl (\b a -> if even a then b+1 else b) 0 ls
423 assert (v1 == (v2, v3))
425partitionByFstM :: Property
427 forAll (listOf1 (chooseInt (intMin, intMax)))
428 $ \ls0 -> monadicIO $ action ls0
433 let f = \x -> if odd x then return (Left x) else return (Right x)
437 (Fold.partitionByFstM f (Fold.take 25 Fold.length) Fold.length)
438 (Stream.fromList ([1 .. 100] :: [Int]))
439 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ([1..49] :: [Int])
440 v3 = foldl (\b a -> if even a then b+1 else b) 0 ([1..49] :: [Int])
441 assert (v1 == (v2, v3))
443partitionByMinM1 :: Property
445 forAll (listOf1 (chooseInt (intMin, intMax)))
446 $ \ls0 -> monadicIO $ action ls0
451 let f = \x -> if odd x then return (Left x) else return (Right x)
455 (Fold.partitionByMinM f Fold.length (Fold.take 25 Fold.length))
456 (Stream.fromList ([1 .. 100] :: [Int]))
457 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ([1..50] :: [Int])
458 v3 = foldl (\b a -> if even a then b+1 else b) 0 ([1..50] :: [Int])
459 assert (v1 == (v2, v3))
461partitionByMinM2 :: Property
463 forAll (listOf1 (chooseInt (intMin, intMax)))
464 $ \ls0 -> monadicIO $ action ls0
469 let f = \x -> if odd x then return (Left x) else return (Right x)
473 (Fold.partitionByMinM f (Fold.take 25 Fold.length) Fold.length)
474 (Stream.fromList ([1 .. 100] :: [Int]))
475 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ([1..49] :: [Int])
476 v3 = foldl (\b a -> if even a then b+1 else b) 0 ([1..49] :: [Int])
477 assert (v1 == (v2, v3))
479teeWithMinLength1 :: Property
481 forAll (listOf1 (chooseInt (intMin, intMax)))
482 $ \ls0 -> monadicIO $ action ls0
489 $ Stream.fold (Fold.teeWithMin (,) (Fold.take 5 Fold.sum) Fold.length)
491 let v2 = Prelude.sum (Prelude.take 5 ls)
492 v3 = Prelude.length (Prelude.take 5 ls)
493 assert (v1 == (v2, v3))
496teeWithMinLength2 :: Property
498 forAll (listOf1 (chooseInt (intMin, intMax)))
499 $ \ls0 -> monadicIO $ action ls0
506 $ Stream.fold (Fold.teeWithMin (,) Fold.sum (Fold.take 5 Fold.length))
508 let v2 = Prelude.sum (Prelude.take 5 ls)
509 v3 = Prelude.length (Prelude.take 5 ls)
510 assert (v1 == (v2, v3))
512teeWithMax :: Property
514 forAll (listOf1 (chooseInt (intMin, intMax)))
515 $ \ls0 -> monadicIO $ action ls0
520 v1 <- run $ Stream.fold (Fold.tee Fold.sum Fold.maximum) $ Stream.fromList ls
521 let v2 = Prelude.sum ls
522 v3 = foldMaybe (greater compare) intMin ls
523 assert (v1 == (v2, v3))
525distribute :: Property
527 forAll (listOf1 (chooseInt (intMin, intMax)))
528 $ \ls0 -> monadicIO $ action ls0
534 run $ Stream.fold (Fold.distribute [Fold.sum, Fold.length]) $ Stream.fromList ls
535 let v2 = Prelude.sum ls
536 v3 = Prelude.length ls
537 assert (v1 == [v2, v3])
542 v1 :: (Int, [String]) <-
544 $ Stream.fold (Fold.partition Fold.sum Fold.toList)
546 [Left 1, Right "abc", Left 3, Right "xy", Right "pp2"]
547 let v2 = (4,["abc","xy","pp2"])
553 v1 :: (Int, [String]) <-
555 $ Stream.fold (Fold.unzip Fold.sum Fold.toList)
556 $ Stream.fromList [(1, "aa"), (2, "bb"), (3, "cc")]
557 let v2 = (6, ["aa", "bb", "cc"])
561postscan = forAll (listOf (chooseInt (intMin, intMax))) $ \ls ->
565 $ Stream.fold (Fold.postscan Fold.sum Fold.toList)
567 let v2 = scanl1 (+) ls
572 forAll (listOf (chooseInt (0, 100))) $ \lst ->
573 forAll (chooseInt (1, 100)) $ \i ->
575 let strm = Stream.fromList lst
576 r1 <- Stream.fold (Fold.many (split i) Fold.toList) strm
577 r2 <- Stream.fold Fold.toList $ Stream.foldMany (split i) strm
582 split i = Fold.take i Fold.toList
584foldBreak :: [Int] -> Property
585foldBreak ls = monadicIO $ do
586 (mbh, rest) <- run $ Stream.foldBreak Fold.one (Stream.fromList ls)
587 rests <- run $ Stream.fold Fold.toList rest
588 assert (mbh == headl ls)
589 listEquals (==) rests (taill ls)
599 let table "SUM" = return Fold.sum
600 table "PRODUCT" = return Fold.product
601 table _ = return Fold.length
602 input = Stream.fromList (
612 ] :: [(String, Int)])
614 (Fold.demuxKvToMap table)
617 Data.Map.fromList [("PRODUCT", 8),("SUM", 4),("abc",3),("xyz",2)]
620demuxWith :: Expectation
622 let getKey x | even x = "SUM"
623 | otherwise = "PRODUCT"
625 getFold "SUM" = return Fold.sum
626 getFold "PRODUCT" = return Fold.product
627 getFold _ = error "demuxWith: bug"
629 input = Stream.fromList [1, 2, 3, 4 :: Int]
631 (Fold.demuxToContainer getKey (getFold . getKey))
634 Data.Map.fromList [("PRODUCT",3),("SUM",6)]
636classifyWith :: Expectation
638 let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
640 (Fold.toContainer fst (Fold.lmap snd Fold.toList))
644 [("ONE",[1.0, 1.1 :: Double]), ("TWO",[2.0, 2.2])]
646classify :: Expectation
652 , ("ONE", (1, 1.1:: Double))
657 (Fold.kvToMap (Fold.lmap snd Fold.toList))
661 [("ONE",[1.0, 1.1 :: Double]), ("TWO",[2.0, 2.2])]
663splitAt :: Expectation
666 (Fold.splitAt 6 Fold.toList Fold.toList)
667 (Stream.fromList "Hello World!")
672scan = forAll (listOf (chooseInt (0, 100))) $ \lst ->
676 $ Stream.fold (Fold.scan Fold.sum Fold.toList)
677 $ Stream.fromList lst
678 let v2 = scanl (+) 0 lst
681topBy :: Bool -> Property
682topBy isTop = forAll (listOf (chooseInt (-50, 100))) $ \ls0 ->
683 monadicIO $ action ls0
689 let n0 = Prelude.length ls
690 n <- liftIO $ generate $ chooseInt (-2, n0 + 2)
693 lst <- Stream.fold (Fold.top n) (Stream.fromList ls) >>= MArray.toList
694 assert ((Prelude.take n . Prelude.reverse . sort) ls == lst)
696 lst <- Stream.fold (Fold.bottom n) (Stream.fromList ls) >>= MArray.toList
697 assert ((Prelude.take n . sort) ls == lst)
707 vals <- Stream.fold Fold.toList
709 $ Stream.postscan Fold.nub
710 $ Stream.fromList [1::Int, 1, 2, 3, 4, 4, 5, 1, 5, 7]
711 assert (vals == [1, 2, 3, 4, 5, 7])
714moduleName = "Data.Fold"
718 describe moduleName $ do
721 prop "mconcat" Main.mconcat
722 prop "foldMap" Main.foldMap
723 prop "foldMapM" Main.foldMapM
725 prop "drain" Main.drain
726 prop "drainBy" Main.drainBy
728 prop "length" Main.length
730 prop "product" product
731 prop "maximumBy" $ maximumBy intMin compare
732 prop "maximum" $ maximum intMin
733 prop "minimumBy" $ minimumBy intMax compare
734 prop "minimum" $ minimum intMax
735 prop "mean" Main.mean
736 prop "stdDev" Main.stdDev
737 prop "variance" Main.variance
738 prop "rollingHashFirstN" rollingHashFirstN
741 prop "toListRev" toListRev
743 prop "demuxWith" demuxWith
744 prop "classifyWith" classifyWith
745 prop "classify" classify
750 prop "find" $ find predicate
751 prop "lookup" Main.lookup
752 prop "findIndex" $ findIndex predicate
753 prop "elemIndex" $ elemIndex 10
755 prop "elem" $ elem 10
756 prop "notElem" $ notElem 10
757 prop "all" $ Main.all predicate
758 prop "any" $ Main.any predicate
762 prop "bottom" Main.bottom
769 prop "postscan" Main.postscan
772 prop "rmapM" Main.rmapM
778 prop "mapMaybe" mapMaybe
783 prop "takeEndBy_" takeEndBy_
784 prop "takeEndByOrMax" takeEndByOrMax
791 prop "teeWithLength" Main.teeWithLength
792 prop "teeWithFstLength" Main.teeWithFstLength
793 prop "teeWithMinLength1" Main.teeWithMinLength1
794 prop "teeWithMinLength2" Main.teeWithMinLength2
795 prop "teeWithMax" Main.teeWithMax
796 prop "partitionByM" Main.partitionByM
797 prop "partitionByFstM" Main.partitionByFstM
798 prop "partitionByMinM1" Main.partitionByMinM1
799 prop "partitionByMinM2" Main.partitionByMinM2
800 prop "distribute" Main.distribute
803 prop "partition" Main.partition
804 prop "partitionByM" partitionByM
807 prop "unzip" Main.unzip
808 prop "splitAt" Main.splitAt
811 prop "many" Main.many
815 prop "foldBreak" foldBreak
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list