1module Main (main) where
3import Data.Semigroup (Sum(..), getSum)
4import Streamly.Test.Common (checkListEqual)
17import Test.QuickCheck.Monadic (monadicIO, assert, run)
19import qualified Prelude
20import qualified Streamly.Internal.Data.Fold as F
21import qualified Streamly.Prelude as S
22import qualified Streamly.Data.Fold as FL
25 (maximum, minimum, elem, notElem, null, product, sum, head, last)
27import Test.Hspec.QuickCheck
44chooseInt :: (Int, Int) -> Gen Int
47{-# INLINE maxStreamLen #-}
51rollingHashFirstN :: Property
53 forAll (choose (0, maxStreamLen)) $ \len ->
54 forAll (choose (0, len)) $ \n ->
55 forAll (vectorOf len (arbitrary :: Gen Int)) $ \vec -> monadicIO $ do
56 a <- run $ S.fold F.rollingHash $ S.take n $ S.fromList vec
57 b <- run $ S.fold (F.rollingHashFirstN n) $ S.fromList vec
60head :: [Int] -> Expectation
61head ls = S.fold FL.head (S.fromList ls) `shouldReturn` headl ls
68length :: [Int] -> Expectation
69length ls = S.fold FL.length (S.fromList ls) `shouldReturn` Prelude.length ls
71sum :: [Int] -> Expectation
72sum ls = S.fold FL.sum (S.fromList ls) `shouldReturn` Prelude.sum ls
74product :: [Int] -> Expectation
76 S.fold FL.product (S.fromList ls) `shouldReturn` Prelude.product ls
78lesser :: (a -> a -> Ordering) -> a -> a -> a
79lesser f x y = if f x y == LT then x else y
81greater :: (a -> a -> Ordering) -> a -> a -> a
82greater f x y = if f x y == GT then x else y
84foldMaybe :: (b -> a -> b) -> b -> [a] -> Maybe b
88 _ -> Just (foldl f acc ls)
90maximumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
91maximumBy genmin f ls =
92 S.fold (FL.maximumBy f) (S.fromList ls)
93 `shouldReturn` foldMaybe (greater f) genmin ls
95maximum :: (Show a, Ord a) => a -> [a] -> Expectation
97 S.fold FL.maximum (S.fromList ls)
98 `shouldReturn` foldMaybe (greater compare) genmin ls
100minimumBy :: (Ord a, Show a) => a -> (a -> a -> Ordering) -> [a] -> Expectation
101minimumBy genmax f ls =
102 S.fold (FL.minimumBy f) (S.fromList ls)
103 `shouldReturn` foldMaybe (lesser f) genmax ls
105minimum :: (Show a, Ord a) => a -> [a] -> Expectation
107 S.fold FL.minimum (S.fromList ls)
108 `shouldReturn` foldMaybe (lesser compare) genmax ls
110toList :: [Int] -> Expectation
111toList ls = S.fold FL.toList (S.fromList ls) `shouldReturn` ls
113safeLast :: [a] -> Maybe a
115safeLast (x:[]) = Just x
116safeLast (_:xs) = safeLast xs
118last :: [String] -> Expectation
119last ls = S.fold FL.last (S.fromList ls) `shouldReturn` safeLast ls
121mapMaybe :: [Int] -> Expectation
127 f = F.mapMaybe maybeEven FL.toList
128 in S.fold f (S.fromList ls) `shouldReturn` filter even ls
130nth :: Int -> [a] -> Maybe a
134 | otherwise = nth (idx - 1) xs
137index :: Int -> [String] -> Expectation
139 let x = S.fold (FL.index idx) (S.fromList ls)
140 in x `shouldReturn` nth idx ls
142find :: (Show a, Eq a) => (a -> Bool) -> [a] -> Expectation
144 y <- S.fold (FL.findIndex f) (S.fromList ls)
147 let fld = S.fold (FL.find f) (S.fromList ls)
148 in fld `shouldReturn` Nothing
150 let fld = S.fold (FL.any f) (S.fromList $ take idx ls)
151 in fld `shouldReturn` False
153neg :: (a -> Bool) -> a -> Bool
156findIndex :: (a -> Bool) -> [a] -> Expectation
158 y <- S.fold (FL.findIndex f) (S.fromList ls)
161 let fld = S.fold (FL.all $ neg f) (S.fromList ls)
162 in fld `shouldReturn` True
166 S.fold (FL.all f) (S.fromList []) `shouldReturn` True
168 S.fold (FL.all f) (S.fromList $ take idx ls)
171predicate :: Int -> Bool
172predicate x = x * x < 100
174elemIndex :: Int -> [Int] -> Expectation
176 y <- S.fold (FL.elemIndex elm) (S.fromList ls)
179 let fld = S.fold (FL.any (== elm)) (S.fromList ls)
180 in fld `shouldReturn` False
182 let fld = S.fold (FL.any (== elm)) (S.fromList $ take idx ls)
183 in fld `shouldReturn` False
185null :: [Int] -> Expectation
187 S.fold FL.null (S.fromList ls)
193elem :: Int -> [Int] -> Expectation
195 y <- S.fold (FL.elem elm) (S.fromList ls)
196 let fld = S.fold (FL.any (== elm)) (S.fromList ls)
199notElem :: Int -> [Int] -> Expectation
201 y <- S.fold (FL.notElem elm) (S.fromList ls)
202 let fld = S.fold (FL.any (== elm)) (S.fromList ls)
203 fld `shouldReturn` not y
205all :: (a -> Bool) -> [a] -> Expectation
207 S.fold (FL.all f) (S.fromList ls) `shouldReturn` Prelude.all f ls
209any :: (a -> Bool) -> [a] -> Expectation
210any f ls = S.fold (FL.any f) (S.fromList ls) `shouldReturn` Prelude.any f ls
212and :: [Bool] -> Expectation
213and ls = S.fold FL.and (S.fromList ls) `shouldReturn` Prelude.and ls
215or :: [Bool] -> Expectation
216or ls = S.fold FL.or (S.fromList ls) `shouldReturn` Prelude.or ls
218ltake :: [Int] -> Property
220 forAll (chooseInt (-1, Prelude.length ls + 2)) $ \n ->
221 S.fold (F.ltake n FL.toList) (S.fromList ls)
222 `shouldReturn` Prelude.take n ls
224sliceSepBy :: Property
226 forAll (listOf (chooseInt (0, 1))) $ \ls ->
228 f = F.sliceSepBy p FL.toList
229 ys = Prelude.takeWhile (not . p) ls
230 in case S.fold f (S.fromList ls) of
231 Right xs -> checkListEqual xs ys
232 Left _ -> property False
234sliceSepByMax :: Property
236 forAll (chooseInt (min_value, max_value)) $ \n ->
237 forAll (listOf (chooseInt (0, 1))) $ \ls ->
239 f = F.sliceSepByMax p n FL.toList
240 ys = Prelude.take n (Prelude.takeWhile (not . p) ls)
241 in case S.fold f (S.fromList ls) of
242 Right xs -> checkListEqual xs ys
243 Left _ -> property False
245chooseFloat :: (Float, Float) -> Gen Float
248drain :: [Int] -> Expectation
249drain ls = S.fold FL.drain (S.fromList ls) `shouldReturn` ()
251drainBy :: [Int] -> Expectation
252drainBy ls = S.fold (FL.drainBy return) (S.fromList ls) `shouldReturn` ()
256 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
257 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
262 v1 <- run $ S.fold FL.mean (S.fromList ls)
263 let v2 = Prelude.sum ls / fromIntegral (Prelude.length ls)
264 assert (abs (v1 - v2) < 0.0001)
268 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
269 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
274 v1 <- run $ S.fold FL.stdDev (S.fromList ls)
275 let avg = Prelude.sum ls / fromIntegral (Prelude.length ls)
276 se = Prelude.sum (fmap (\x -> (x - avg) * (x - avg)) ls)
277 sd = sqrt $ se / fromIntegral (Prelude.length ls)
278 assert (abs (v1 - sd) < 0.0001 )
282 forAll (listOf1 (chooseFloat (-100.0, 100.0)))
283 $ \ls0 -> withMaxSuccess 1000 $ monadicIO $ action ls0
288 v1 <- run $ S.fold FL.variance (S.fromList ls)
289 let avg = Prelude.sum ls / fromIntegral (Prelude.length ls)
290 se = Prelude.sum (fmap (\x -> (x - avg) * (x - avg)) ls)
291 vr = se / fromIntegral (Prelude.length ls)
292 assert (abs (v1 - vr) < 0.01 )
296 forAll (listOf1 (chooseInt (intMin, intMax)))
297 $ \ls0 -> monadicIO $ action ls0
302 v1 <- run $ S.fold FL.mconcat (S.map Sum $ S.fromList ls)
303 let v2 = Prelude.sum ls
304 assert (getSum v1 == v2)
308 forAll (listOf1 (chooseInt (intMin, intMax)))
309 $ \ls0 -> monadicIO $ action ls0
314 v1 <- run $ S.fold (FL.foldMap Sum) $ S.fromList ls
315 let v2 = Prelude.sum ls
316 assert (getSum v1 == v2)
320 forAll (listOf1 (chooseInt (intMin, intMax)))
321 $ \ls0 -> monadicIO $ action ls0
326 v1 <- run $ S.fold (FL.foldMapM (return . Sum)) $ S.fromList ls
327 let v2 = Prelude.sum ls
328 assert (getSum v1 == v2)
332 forAll (chooseInt (1, 15))
333 $ \key0 ->monadicIO $ action key0
338 let ls = [(1, "first"), (2, "second"), (3, "third"), (4, "fourth")
339 , (5, "fifth"), (6, "fifth+first"), (7, "fifth+second")
340 , (8, "fifth+third"), (9, "fifth+fourth")
341 , (10, "fifth+fifth")]
342 v1 <- run $ S.fold (FL.lookup key) $ S.fromList ls
343 let v2 = Prelude.lookup key ls
348 forAll (listOf1 (chooseInt (intMin, intMax)))
349 $ \ls0 -> monadicIO $ action ls0
354 let addLen x = return $ x + Prelude.length ls
355 fld = FL.mapM addLen FL.sum
356 v2 = foldl (+) (Prelude.length ls) ls
357 v1 <- run $ S.fold fld $ S.fromList ls
360teeWithLength :: Property
362 forAll (listOf1 (chooseInt (intMin, intMax)))
363 $ \ls0 -> monadicIO $ action ls0
368 v1 <- run $ S.fold (FL.tee FL.sum FL.length) $ S.fromList ls
369 let v2 = Prelude.sum ls
370 v3 = Prelude.length ls
371 assert (v1 == (v2, v3))
373teeWithMax :: Property
375 forAll (listOf1 (chooseInt (intMin, intMax)))
376 $ \ls0 -> monadicIO $ action ls0
381 v1 <- run $ S.fold (FL.tee FL.sum FL.maximum) $ S.fromList ls
382 let v2 = Prelude.sum ls
383 v3 = foldMaybe (greater compare) intMin ls
384 assert (v1 == (v2, v3))
386distribute :: Property
388 forAll (listOf1 (chooseInt (intMin, intMax)))
389 $ \ls0 -> monadicIO $ action ls0
394 v1 <- run $ S.fold (FL.distribute [FL.sum, FL.length]) $ S.fromList ls
395 let v2 = Prelude.sum ls
396 v3 = Prelude.length ls
397 assert (v1 == [v2, v3])
402 v1 :: (Int, [String]) <-
404 $ S.fold (FL.partition FL.sum FL.toList)
406 [Left 1, Right "abc", Left 3, Right "xy", Right "pp2"]
407 let v2 = (4,["abc","xy","pp2"])
413 v1 :: (Int, [String]) <-
415 $ S.fold (FL.unzip FL.sum FL.toList)
416 $ S.fromList [(1, "aa"), (2, "bb"), (3, "cc")]
417 let v2 = (6, ["aa", "bb", "cc"])
422 describe "Fold s" $ do
423 prop "RollingHashFirstN" rollingHashFirstN
427 prop "Length" Main.length
429 prop "Product" product
430 prop "MaximumBy" $ maximumBy intMin compare
431 prop "Maximum" $ maximum intMin
432 prop "MinimumBy" $ minimumBy intMax compare
433 prop "Minimum" $ minimum intMax
435 prop "Find" $ find predicate
436 prop "FindIndex" $ findIndex predicate
437 prop "ElemIndex" $ elemIndex 10
439 prop "Elem" $ elem 10
440 prop "NotElem" $ notElem 10
441 prop "All" $ Main.all predicate
442 prop "Any" $ Main.any predicate
445 prop "mapMaybe" mapMaybe
447 prop "sliceSepBy" sliceSepBy
448 prop "sliceSepByMax" sliceSepByMax
449 prop "drain" Main.drain
450 prop "drainBy" Main.drainBy
451 prop "mean" Main.mean
452 prop "stdDev" Main.stdDev
453 prop "variance" Main.variance
454 prop "mconcat" Main.mconcat
455 prop "foldMap" Main.foldMap
456 prop "foldMapM" Main.foldMapM
457 prop "lookup" Main.lookup
458 prop "mapM" Main.mapM
459 prop "teeWithLength" Main.teeWithLength
460 prop "teeWithMax" Main.teeWithMax
461 prop "distribute" Main.distribute
462 prop "partition" Main.partition
463 prop "unzip" Main.unzip
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