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.MutArray as MArray
27import qualified Streamly.Internal.Data.Fold as Fold
28import qualified Streamly.Internal.Data.Stream as Stream
31 (maximum, minimum, elem, notElem, null, product, sum, head, last, take)
33import Test.Hspec.QuickCheck
50chooseInt :: (Int, Int) -> Gen Int
53{-# INLINE maxStreamLen #-}
57rollingHashFirstN :: Property
59 forAll (choose (0, maxStreamLen)) $ \len ->
60 forAll (choose (0, len)) $ \n ->
61 forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec ->
64 $ Stream.fold Fold.rollingHash
68 $ Stream.fold (Fold.rollingHashFirstN n)
72head :: [Int] -> Expectation
73head ls = Stream.fold Fold.one (Stream.fromList ls) `shouldReturn` headl ls
75headl :: [a] -> Maybe a
79length :: [Int] -> Expectation
80length ls = Stream.fold Fold.length (Stream.fromList ls) `shouldReturn` Prelude.length ls
82sum :: [Int] -> Expectation
83sum ls = Stream.fold Fold.sum (Stream.fromList ls) `shouldReturn` Prelude.sum ls
85product :: [Int] -> Expectation
87 Stream.fold Fold.product (Stream.fromList ls) `shouldReturn` Prelude.product ls
89lesser :: (a -> a -> Ordering) -> a -> a -> a
90lesser f x y = if f x y == LT then x else y
92greater :: (a -> a -> Ordering) -> a -> a -> a
93greater f x y = if f x y == GT then x else y
95foldMaybe :: (b -> a -> b) -> b -> [a] -> Maybe b
99 _ -> Just (foldl f acc ls)
101maximumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
102maximumBy genmin f ls =
103 Stream.fold (Fold.maximumBy f) (Stream.fromList ls)
104 `shouldReturn` foldMaybe (greater f) genmin ls
106maximum :: (Show a, Ord a) => a -> [a] -> Expectation
108 Stream.fold Fold.maximum (Stream.fromList ls)
109 `shouldReturn` foldMaybe (greater compare) genmin ls
111minimumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
112minimumBy genmax f ls =
113 Stream.fold (Fold.minimumBy f) (Stream.fromList ls)
114 `shouldReturn` foldMaybe (lesser f) genmax ls
116minimum :: (Show a, Ord a) => a -> [a] -> Expectation
118 Stream.fold Fold.minimum (Stream.fromList ls)
119 `shouldReturn` foldMaybe (lesser compare) genmax ls
121toList :: [Int] -> Expectation
122toList ls = Stream.fold Fold.toList (Stream.fromList ls) `shouldReturn` ls
124toListRev :: [Int] -> Expectation
125toListRev ls = Stream.fold Fold.toListRev (Stream.fromList ls) `shouldReturn` reverse ls
127safeLast :: [a] -> Maybe a
129safeLast (x:[]) = Just x
130safeLast (_:xs) = safeLast xs
132last :: [String] -> Expectation
133last ls = Stream.fold Fold.last (Stream.fromList ls) `shouldReturn` safeLast ls
135mapMaybe :: [Int] -> Expectation
141 f = Fold.mapMaybe maybeEven Fold.toList
142 in Stream.fold f (Stream.fromList ls) `shouldReturn` filter even ls
144nth :: Int -> [a] -> Maybe a
148 | otherwise = nth (idx - 1) xs
151index :: Int -> [String] -> Expectation
153 let x = Stream.fold (Fold.index idx) (Stream.fromList ls)
154 in x `shouldReturn` nth idx ls
156find :: (Show a, Eq a) => (a -> Bool) -> [a] -> Expectation
158 y <- Stream.fold (Fold.findIndex f) (Stream.fromList ls)
161 let fld = Stream.fold (Fold.find f) (Stream.fromList ls)
162 in fld `shouldReturn` Nothing
164 let fld = Stream.fold (Fold.any f) (Stream.fromList $ Prelude.take idx ls)
165 in fld `shouldReturn` False
167neg :: (a -> Bool) -> a -> Bool
170findIndex :: (a -> Bool) -> [a] -> Expectation
172 y <- Stream.fold (Fold.findIndex f) (Stream.fromList ls)
175 let fld = Stream.fold (Fold.all $ neg f) (Stream.fromList ls)
176 in fld `shouldReturn` True
180 Stream.fold (Fold.all f) (Stream.fromList []) `shouldReturn` True
182 Stream.fold (Fold.all f) (Stream.fromList $ Prelude.take idx ls)
185predicate :: Int -> Bool
186predicate x = x * x < 100
188elemIndex :: Int -> [Int] -> Expectation
190 y <- Stream.fold (Fold.elemIndex elm) (Stream.fromList ls)
193 let fld = Stream.fold (Fold.any (== elm)) (Stream.fromList ls)
194 in fld `shouldReturn` False
199 (Stream.fromList $ Prelude.take idx ls)
200 in fld `shouldReturn` False
202null :: [Int] -> Expectation
204 Stream.fold Fold.null (Stream.fromList ls)
210elem :: Int -> [Int] -> Expectation
212 y <- Stream.fold (Fold.elem elm) (Stream.fromList ls)
213 let fld = Stream.fold (Fold.any (== elm)) (Stream.fromList ls)
216notElem :: Int -> [Int] -> Expectation
218 y <- Stream.fold (Fold.notElem elm) (Stream.fromList ls)
219 let fld = Stream.fold (Fold.any (== elm)) (Stream.fromList ls)
220 fld `shouldReturn` not y
222all :: (a -> Bool) -> [a] -> Expectation
224 Stream.fold (Fold.all f) (Stream.fromList ls) `shouldReturn` Prelude.all f ls
226any :: (a -> Bool) -> [a] -> Expectation
227any f ls = Stream.fold (Fold.any f) (Stream.fromList ls) `shouldReturn` Prelude.any f ls
229and :: [Bool] -> Expectation
230and ls = Stream.fold Fold.and (Stream.fromList ls) `shouldReturn` Prelude.and ls
232or :: [Bool] -> Expectation
233or ls = Stream.fold Fold.or (Stream.fromList ls) `shouldReturn` Prelude.or ls
235take :: [Int] -> Property
237 forAll (chooseInt (-1, Prelude.length ls + 2)) $ \n ->
238 Stream.fold (Fold.take n Fold.toList) (Stream.fromList ls)
239 `shouldReturn` Prelude.take n ls
241takeEndBy_ :: Property
243 forAll (listOf (chooseInt (0, 1))) $ \ls ->
245 f = Fold.takeEndBy_ p Fold.toList
246 ys = Prelude.takeWhile (not . p) ls
247 in case Stream.fold f (Stream.fromList ls) of
248 Right xs -> checkListEqual xs ys
249 Left _ -> property False
251takeEndByOrMax :: Property
253 forAll (chooseInt (min_value, max_value)) $ \n ->
254 forAll (listOf (chooseInt (0, 1))) $ \ls ->
256 f = Fold.takeEndBy_ p (Fold.take n Fold.toList)
257 ys = Prelude.take n (Prelude.takeWhile (not . p) ls)
258 in case Stream.fold f (Stream.fromList ls) of
259 Right xs -> checkListEqual xs ys
260 Left _ -> property False
262chooseFloat :: (Float, Float) -> Gen Float
265drain :: [Int] -> Expectation
266drain ls = Stream.fold Fold.drain (Stream.fromList ls) `shouldReturn` ()
268drainBy :: [Int] -> Expectation
269drainBy ls = Stream.fold (Fold.drainBy return) (Stream.fromList ls) `shouldReturn` ()
273 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
274 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
279 v1 <- run $ Stream.fold Fold.mean (Stream.fromList ls)
280 let v2 = Prelude.sum ls / fromIntegral (Prelude.length ls)
281 assert (abs (v1 - v2) < 0.0001)
285 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
286 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
291 v1 <- run $ Stream.fold Fold.stdDev (Stream.fromList ls)
292 let avg = Prelude.sum ls / fromIntegral (Prelude.length ls)
293 se = Prelude.sum (fmap (\x -> (x - avg) * (x - avg)) ls)
294 sd = sqrt $ se / fromIntegral (Prelude.length ls)
295 assert (abs (v1 - sd) < 0.0001 )
299 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
300 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
305 v1 <- run $ Stream.fold Fold.variance (Stream.fromList ls)
306 let avg = Prelude.sum ls / fromIntegral (Prelude.length ls)
307 se = Prelude.sum (fmap (\x -> (x - avg) * (x - avg)) ls)
308 vr = se / fromIntegral (Prelude.length ls)
309 assert (abs (v1 - vr) < 0.01 )
313 forAll (listOf1 (chooseInt (intMin, intMax)))
314 $ \ls0 -> monadicIO $ action ls0
319 v1 <- run $ Stream.fold Fold.mconcat (fmap Sum $ Stream.fromList ls)
320 let v2 = Prelude.sum ls
321 assert (getSum v1 == v2)
325 forAll (listOf1 (chooseInt (intMin, intMax)))
326 $ \ls0 -> monadicIO $ action ls0
331 v1 <- run $ Stream.fold (Fold.foldMap Sum) $ Stream.fromList ls
332 let v2 = Prelude.sum ls
333 assert (getSum v1 == v2)
337 forAll (listOf1 (chooseInt (intMin, intMax)))
338 $ \ls0 -> monadicIO $ action ls0
343 v1 <- run $ Stream.fold (Fold.foldMapM (return . Sum)) $ Stream.fromList ls
344 let v2 = Prelude.sum ls
345 assert (getSum v1 == v2)
349 forAll (chooseInt (1, 15))
350 $ \key0 ->monadicIO $ action key0
355 let ls = [ (1, "first"), (2, "second"), (3, "third"), (4, "fourth")
356 , (5, "fifth"), (6, "fifth+first"), (7, "fifth+second")
357 , (8, "fifth+third"), (9, "fifth+fourth")
358 , (10, "fifth+fifth")
360 v1 <- run $ Stream.fold (Fold.lookup key) $ Stream.fromList ls
361 let v2 = Prelude.lookup key ls
366 forAll (listOf1 (chooseInt (intMin, intMax)))
367 $ \ls0 -> monadicIO $ action ls0
372 let addLen x = return $ x + Prelude.length ls
373 fld = Fold.rmapM addLen Fold.sum
374 v2 = foldl (+) (Prelude.length ls) ls
375 v1 <- run $ Stream.fold fld $ Stream.fromList ls
378teeWithLength :: Property
380 forAll (listOf1 (chooseInt (intMin, intMax)))
381 $ \ls0 -> monadicIO $ action ls0
386 v1 <- run $ Stream.fold (Fold.tee Fold.sum Fold.length) $ Stream.fromList ls
387 let v2 = Prelude.sum ls
388 v3 = Prelude.length ls
389 assert (v1 == (v2, v3))
391teeWithFstLength :: Property
393 forAll (listOf1 (chooseInt (intMin, intMax)))
394 $ \ls0 -> monadicIO $ action ls0
401 $ Stream.fold (Fold.teeWithFst (,) (Fold.take 5 Fold.sum) Fold.length)
403 let v2 = Prelude.sum (Prelude.take 5 ls)
404 v3 = Prelude.length (Prelude.take 5 ls)
405 assert (v1 == (v2, v3))
407partitionByM :: Property
409 forAll (listOf1 (chooseInt (intMin, intMax)))
410 $ \ls0 -> monadicIO $ action ls0
415 let f = \x -> if odd x then return (Left x) else return (Right x)
418 $ Stream.fold (Fold.partitionByM f Fold.length Fold.length)
420 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ls
421 v3 = foldl (\b a -> if even a then b+1 else b) 0 ls
422 assert (v1 == (v2, v3))
424partitionByFstM :: Property
426 forAll (listOf1 (chooseInt (intMin, intMax)))
427 $ \ls0 -> monadicIO $ action ls0
432 let f = \x -> if odd x then return (Left x) else return (Right x)
436 (Fold.partitionByFstM f (Fold.take 25 Fold.length) Fold.length)
437 (Stream.fromList ([1 .. 100] :: [Int]))
438 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ([1..49] :: [Int])
439 v3 = foldl (\b a -> if even a then b+1 else b) 0 ([1..49] :: [Int])
440 assert (v1 == (v2, v3))
442partitionByMinM1 :: Property
444 forAll (listOf1 (chooseInt (intMin, intMax)))
445 $ \ls0 -> monadicIO $ action ls0
450 let f = \x -> if odd x then return (Left x) else return (Right x)
454 (Fold.partitionByMinM f Fold.length (Fold.take 25 Fold.length))
455 (Stream.fromList ([1 .. 100] :: [Int]))
456 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ([1..50] :: [Int])
457 v3 = foldl (\b a -> if even a then b+1 else b) 0 ([1..50] :: [Int])
458 assert (v1 == (v2, v3))
460partitionByMinM2 :: Property
462 forAll (listOf1 (chooseInt (intMin, intMax)))
463 $ \ls0 -> monadicIO $ action ls0
468 let f = \x -> if odd x then return (Left x) else return (Right x)
472 (Fold.partitionByMinM f (Fold.take 25 Fold.length) Fold.length)
473 (Stream.fromList ([1 .. 100] :: [Int]))
474 let v2 = foldl (\b a -> if odd a then b+1 else b) 0 ([1..49] :: [Int])
475 v3 = foldl (\b a -> if even a then b+1 else b) 0 ([1..49] :: [Int])
476 assert (v1 == (v2, v3))
478teeWithMinLength1 :: Property
480 forAll (listOf1 (chooseInt (intMin, intMax)))
481 $ \ls0 -> monadicIO $ action ls0
488 $ Stream.fold (Fold.teeWithMin (,) (Fold.take 5 Fold.sum) Fold.length)
490 let v2 = Prelude.sum (Prelude.take 5 ls)
491 v3 = Prelude.length (Prelude.take 5 ls)
492 assert (v1 == (v2, v3))
495teeWithMinLength2 :: Property
497 forAll (listOf1 (chooseInt (intMin, intMax)))
498 $ \ls0 -> monadicIO $ action ls0
505 $ Stream.fold (Fold.teeWithMin (,) Fold.sum (Fold.take 5 Fold.length))
507 let v2 = Prelude.sum (Prelude.take 5 ls)
508 v3 = Prelude.length (Prelude.take 5 ls)
509 assert (v1 == (v2, v3))
511teeWithMax :: Property
513 forAll (listOf1 (chooseInt (intMin, intMax)))
514 $ \ls0 -> monadicIO $ action ls0
519 v1 <- run $ Stream.fold (Fold.tee Fold.sum Fold.maximum) $ Stream.fromList ls
520 let v2 = Prelude.sum ls
521 v3 = foldMaybe (greater compare) intMin ls
522 assert (v1 == (v2, v3))
524distribute :: Property
526 forAll (listOf1 (chooseInt (intMin, intMax)))
527 $ \ls0 -> monadicIO $ action ls0
533 run $ Stream.fold (Fold.distribute [Fold.sum, Fold.length]) $ Stream.fromList ls
534 let v2 = Prelude.sum ls
535 v3 = Prelude.length ls
536 assert (v1 == [v2, v3])
541 v1 :: (Int, [String]) <-
543 $ Stream.fold (Fold.partition Fold.sum Fold.toList)
545 [Left 1, Right "abc", Left 3, Right "xy", Right "pp2"]
546 let v2 = (4,["abc","xy","pp2"])
552 v1 :: (Int, [String]) <-
554 $ Stream.fold (Fold.unzip Fold.sum Fold.toList)
555 $ Stream.fromList [(1, "aa"), (2, "bb"), (3, "cc")]
556 let v2 = (6, ["aa", "bb", "cc"])
560postscan = forAll (listOf (chooseInt (intMin, intMax))) $ \ls ->
564 $ Stream.fold (Fold.postscan Fold.sum Fold.toList)
566 let v2 = scanl1 (+) ls
571 forAll (listOf (chooseInt (0, 100))) $ \lst ->
572 forAll (chooseInt (1, 100)) $ \i ->
574 let strm = Stream.fromList lst
575 r1 <- Stream.fold (Fold.many (split i) Fold.toList) strm
576 r2 <- Stream.fold Fold.toList $ Stream.foldMany (split i) strm
581 split i = Fold.take i Fold.toList
583foldBreak :: [Int] -> Property
584foldBreak ls = monadicIO $ do
585 (mbh, rest) <- run $ Stream.foldBreak Fold.one (Stream.fromList ls)
586 rests <- run $ Stream.fold Fold.toList rest
587 assert (mbh == headl ls)
588 listEquals (==) rests (taill ls)
598 let table "SUM" = return Fold.sum
599 table "PRODUCT" = return Fold.product
600 table _ = return Fold.length
601 input = Stream.fromList (
611 ] :: [(String, Int)])
613 (Fold.demuxKvToMap table)
616 Data.Map.fromList [("PRODUCT", 8),("SUM", 4),("abc",3),("xyz",2)]
619demuxWith :: Expectation
621 let getKey x | even x = "SUM"
622 | otherwise = "PRODUCT"
624 getFold "SUM" = return Fold.sum
625 getFold "PRODUCT" = return Fold.product
626 getFold _ = error "demuxWith: bug"
628 input = Stream.fromList [1, 2, 3, 4 :: Int]
630 (Fold.demuxToContainer getKey (getFold . getKey))
633 Data.Map.fromList [("PRODUCT",3),("SUM",6)]
635classifyWith :: Expectation
637 let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]
639 (Fold.toContainer fst (Fold.lmap snd Fold.toList))
643 [("ONE",[1.0, 1.1 :: Double]), ("TWO",[2.0, 2.2])]
645classify :: Expectation
651 , ("ONE", (1, 1.1:: Double))
656 (Fold.kvToMap (Fold.lmap snd Fold.toList))
660 [("ONE",[1.0, 1.1 :: Double]), ("TWO",[2.0, 2.2])]
662splitAt :: Expectation
665 (Fold.splitAt 6 Fold.toList Fold.toList)
666 (Stream.fromList "Hello World!")
671scan = forAll (listOf (chooseInt (0, 100))) $ \lst ->
675 $ Stream.fold (Fold.scan Fold.sum Fold.toList)
676 $ Stream.fromList lst
677 let v2 = scanl (+) 0 lst
680topBy :: Bool -> Property
681topBy isTop = forAll (listOf (chooseInt (-50, 100))) $ \ls0 ->
682 monadicIO $ action ls0
688 let n0 = Prelude.length ls
689 n <- liftIO $ generate $ chooseInt (-2, n0 + 2)
692 lst <- Stream.fold (Fold.top n) (Stream.fromList ls) >>= MArray.toList
693 assert ((Prelude.take n . Prelude.reverse . sort) ls == lst)
695 lst <- Stream.fold (Fold.bottom n) (Stream.fromList ls) >>= MArray.toList
696 assert ((Prelude.take n . sort) ls == lst)
706 vals <- Stream.fold Fold.toList
708 $ Stream.postscan Fold.nub
709 $ Stream.fromList [1::Int, 1, 2, 3, 4, 4, 5, 1, 5, 7]
710 assert (vals == [1, 2, 3, 4, 5, 7])
713moduleName = "Data.Fold"
717 describe moduleName $ do
720 prop "mconcat" Main.mconcat
721 prop "foldMap" Main.foldMap
722 prop "foldMapM" Main.foldMapM
724 prop "drain" Main.drain
725 prop "drainBy" Main.drainBy
727 prop "length" Main.length
729 prop "product" product
730 prop "maximumBy" $ maximumBy intMin compare
731 prop "maximum" $ maximum intMin
732 prop "minimumBy" $ minimumBy intMax compare
733 prop "minimum" $ minimum intMax
734 prop "mean" Main.mean
735 prop "stdDev" Main.stdDev
736 prop "variance" Main.variance
737 prop "rollingHashFirstN" rollingHashFirstN
740 prop "toListRev" toListRev
742 prop "demuxWith" demuxWith
743 prop "classifyWith" classifyWith
744 prop "classify" classify
749 prop "find" $ find predicate
750 prop "lookup" Main.lookup
751 prop "findIndex" $ findIndex predicate
752 prop "elemIndex" $ elemIndex 10
754 prop "elem" $ elem 10
755 prop "notElem" $ notElem 10
756 prop "all" $ Main.all predicate
757 prop "any" $ Main.any predicate
761 prop "bottom" Main.bottom
768 prop "postscan" Main.postscan
771 prop "rmapM" Main.rmapM
777 prop "mapMaybe" mapMaybe
782 prop "takeEndBy_" takeEndBy_
783 prop "takeEndByOrMax" takeEndByOrMax
790 prop "teeWithLength" Main.teeWithLength
791 prop "teeWithFstLength" Main.teeWithFstLength
792 prop "teeWithMinLength1" Main.teeWithMinLength1
793 prop "teeWithMinLength2" Main.teeWithMinLength2
794 prop "teeWithMax" Main.teeWithMax
795 prop "partitionByM" Main.partitionByM
796 prop "partitionByFstM" Main.partitionByFstM
797 prop "partitionByMinM1" Main.partitionByMinM1
798 prop "partitionByMinM2" Main.partitionByMinM2
799 prop "distribute" Main.distribute
802 prop "partition" Main.partition
803 prop "partitionByM" partitionByM
806 prop "unzip" Main.unzip
807 prop "splitAt" Main.splitAt
810 prop "many" Main.many
814 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