on 43dda21 help sign in
708 lines 25 kB history raw
1-- |
2-- Module : Main
3-- Copyright : (c) 2020 Composewell Technologies
4--
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
7-- Stability : experimental
8-- Portability : GHC
9--
10module Main (main) where
12import Streamly.Internal.Data.Unfold (Unfold)
14import qualified Data.List as List
15import qualified Prelude
16import qualified Streamly.Internal.Data.Fold as Fold
17import qualified Streamly.Internal.Data.Unfold as UF
18import qualified Streamly.Internal.Data.Stream.IsStream as S
19import qualified Streamly.Internal.Data.Stream.StreamD as D
20import qualified Streamly.Internal.Data.Stream.StreamK as K
22import Control.Monad.Trans.State.Strict
23import Data.Functor.Identity
24import Prelude hiding (const, take, drop, concat, mapM)
25import Streamly.Prelude (SerialT)
26import Test.Hspec as H
27import Test.Hspec.QuickCheck
28import Test.QuickCheck
29import Test.QuickCheck.Function
31-------------------------------------------------------------------------------
32-- Helper functions
33-------------------------------------------------------------------------------
35-- | @testUnfoldM unf seed initial final xs@, runs an unfold under state monad
36-- using @initial@ as the initial state. @final@ is the expected state after
37-- running it and @xs@ is the list of elements the stream must produce.
38testUnfoldM ::
39 (Eq s, Eq b) => Unfold (State s) a b -> a -> s -> s -> [b] -> Bool
40testUnfoldM unf seed si sf lst = evalState action si
42 where
44 action = do
45 x <- S.toList $ S.unfold unf seed
46 y <- get
47 return $ x == lst && y == sf
49testUnfoldMD :: Unfold (State Int) a Int -> a -> Int -> Int -> [Int] -> Bool
50testUnfoldMD = testUnfoldM
52-- | This is similar to 'testUnfoldM' but without the state monad.
53testUnfold :: Eq b => Unfold Identity a b -> a -> [b] -> Bool
54testUnfold unf seed lst = runIdentity action
56 where
58 action = do
59 x <- S.toList $ S.unfold unf seed
60 return $ x == lst
62testUnfoldD :: Unfold Identity a Int -> a -> [Int] -> Bool
63testUnfoldD = testUnfold
65-------------------------------------------------------------------------------
66-- Operations on input
67-------------------------------------------------------------------------------
69lmapM :: Bool
70lmapM =
71 let unf = UF.lmapM (\x -> modify (+ 1) >> return x) (UF.function id)
72 in testUnfoldMD unf 1 0 1 [1]
74both :: Bool
75both =
76 let unf = UF.both 1 (UF.function id)
77 in testUnfold unf undefined ([1] :: [Int])
79first :: Bool
80first =
81 let unf = UF.first 1 (UF.function id)
82 in testUnfold unf 2 ([(1, 2)] :: [(Int, Int)])
84second :: Bool
85second =
86 let unf = UF.second 1 (UF.function id)
87 in testUnfold unf 2 ([(2, 1)] :: [(Int, Int)])
89discardFirst :: Bool
90discardFirst =
91 let unf = UF.discardFirst (UF.function id)
92 in testUnfold unf ((1, 2) :: (Int, Int)) [2]
94discardSecond :: Bool
95discardSecond =
96 let unf = UF.discardSecond (UF.function id)
97 in testUnfold unf ((1, 2) :: (Int, Int)) [1]
99swap :: Bool
100swap =
101 let unf = UF.swap (UF.function id)
102 in testUnfold unf ((1, 2) :: (Int, Int)) [(2, 1)]
104-------------------------------------------------------------------------------
105-- Stream generation
106-------------------------------------------------------------------------------
108fromStream :: Property
109fromStream =
110 property
111 $ \list ->
112 testUnfoldD
113 UF.fromStream
114 (S.fromList list :: SerialT Identity Int)
115 list
117fromStreamD :: Property
118fromStreamD =
119 property
120 $ \list -> testUnfoldD UF.fromStreamD (D.fromList list) (list :: [Int])
122fromStreamK :: Property
123fromStreamK =
124 property
125 $ \list -> testUnfoldD UF.fromStreamK (K.fromList list) (list :: [Int])
127nilM :: Bool
128nilM =
129 let unf = UF.nilM put
130 in testUnfoldMD unf 1 0 1 []
132consM :: Bool
133consM =
134 let cns = UF.consM (\a -> modify (+ a) >> get)
135 unf = cns $ cns $ UF.nilM $ \a -> modify (+ a)
136 in testUnfoldMD unf 1 0 3 [1, 2]
138functionM :: Bool
139functionM =
140 let unf = UF.functionM (\a -> modify (+ a) >> get)
141 in testUnfoldMD unf 1 0 1 [1]
143const :: Bool
144const =
145 let unf = UF.fromEffect (modify (+ 1) >> get)
146 in testUnfoldMD unf (0 :: Int) 0 1 [1]
148unfoldrM :: Property
149unfoldrM =
150 property
151 $ \gen ->
152 let genA = apply gen :: Int -> Maybe (Int, Int)
153 genM x = modify (+ 1) >> return (genA x)
154 list = Prelude.take 100 $ List.unfoldr genA 1
155 unf = UF.take 100 $ UF.unfoldrM genM
156 ll = length list
157 fs = if ll < 100 then ll + 1 else 100
158 in testUnfoldMD unf 1 0 fs list
160fromListM :: Property
161fromListM =
162 property
163 $ \list ->
164 let listM = Prelude.map (\x -> modify (+ 1) >> return x) list
165 in testUnfoldMD UF.fromListM listM 0 (length list) list
167replicateM :: Property
168replicateM =
169 property
170 $ \i ->
171 let ns = max 0 i
172 seed = modify (+ 1) >> get
173 in testUnfoldMD (UF.replicateM i) seed 0 ns [1 .. i]
175repeatM :: Bool
176repeatM =
177 testUnfoldMD (UF.take 10 UF.repeatM) (modify (+ 1) >> get) 0 10 [1 .. 10]
179iterateM :: Property
180iterateM =
181 property
182 $ \next ->
183 let nextA = apply next :: Int -> Int
184 nextM x = modify (+ 1) >> return (nextA x)
185 list = Prelude.take 100 $ List.iterate nextA 1
186 unf = UF.take 100 $ UF.iterateM nextM
187 in testUnfoldMD unf (modify (+ 10) >> return 1) 0 110 list
189fromIndicesM :: Property
190fromIndicesM =
191 property
192 $ \indF ->
193 let indFA = apply indF :: Int -> Int
194 indFM x = modify (+ 1) >> return (indFA x)
195 list = Prelude.take 100 $ Prelude.map indFA [1 ..]
196 unf = UF.take 100 $ UF.fromIndicesM indFM
197 in testUnfoldMD unf 1 0 (length list) list
199-------------------------------------------------------------------------------
200-- Test for Num type
201-------------------------------------------------------------------------------
202enumerateFromNum :: Property
203enumerateFromNum =
204 property
205 $ \f ->
206 let unf = UF.take 50 UF.enumerateFromNum
207 in testUnfold unf (f :: Int) $
208 Prelude.take 50 $ Prelude.enumFrom f
210enumerateFromThenNum :: Property
211enumerateFromThenNum =
212 property
213 $ \f th ->
214 let unf = UF.take 50 UF.enumerateFromThenNum
215 in testUnfold unf (f :: Int, th) $
216 Prelude.take 50 $ Prelude.enumFromThen f th
218-------------------------------------------------------------------------------
219-- Test for Integral type
220-------------------------------------------------------------------------------
221enumerateFromIntegral :: Property
222enumerateFromIntegral =
223 property
224 $ \f ->
225 let unf = UF.take 50 UF.enumerateFromIntegral
226 in testUnfold unf (f :: Integer) $
227 Prelude.take 50 $ Prelude.enumFrom f
229enumerateFromThenIntegral :: Property
230enumerateFromThenIntegral =
231 property
232 $ \f th ->
233 let unf = UF.take 50 UF.enumerateFromThenIntegral
234 in testUnfold unf (f :: Integer, th) $
235 Prelude.take 50 $ Prelude.enumFromThen f th
237enumerateFromThenToIntegral :: Property
238enumerateFromThenToIntegral =
239 property
240 $ \f th to ->
241 let unf = UF.take 50 UF.enumerateFromThenToIntegral
242 in testUnfold unf (f :: Integer, th, to) $
243 Prelude.take 50 $ Prelude.enumFromThenTo f th to
245enumerateFromToIntegral :: Property
246enumerateFromToIntegral =
247 property
248 $ \f to ->
249 let unf = UF.take 50 UF.enumerateFromToIntegral
250 in testUnfold unf (f :: Integer, to) $
251 Prelude.take 50 $ Prelude.enumFromTo f to
253enumerateFromIntegralBounded :: Property
254enumerateFromIntegralBounded =
255 property
256 $ \f ->
257 let unf = UF.take 50 UF.enumerateFromIntegralBounded
258 in testUnfold unf (f :: Int) $
259 Prelude.take 50 $ Prelude.enumFrom f
261enumerateFromThenIntegralBounded :: Property
262enumerateFromThenIntegralBounded =
263 property
264 $ \f th ->
265 let unf = UF.take 50 UF.enumerateFromThenIntegralBounded
266 in testUnfold unf (f :: Int, th) $
267 Prelude.take 50 $ Prelude.enumFromThen f th
269enumerateFromToIntegralBounded :: Property
270enumerateFromToIntegralBounded =
271 property
272 $ \f to ->
273 let unf = UF.take 50 UF.enumerateFromToIntegralBounded
274 in testUnfold unf (f :: Int, to) $
275 Prelude.take 50 $ Prelude.enumFromTo f to
277enumerateFromThenToIntegralBounded :: Property
278enumerateFromThenToIntegralBounded =
279 property
280 $ \f th to ->
281 let unf = UF.take 50 UF.enumerateFromThenToIntegralBounded
282 in testUnfold unf (f :: Int, th, to) $
283 Prelude.take 50 $ Prelude.enumFromThenTo f th to
285enumerateFromSmallBounded :: Property
286enumerateFromSmallBounded =
287 property
288 $ \f ->
289 let unf = UF.take 50 UF.enumerateFromSmallBounded
290 in testUnfold unf (f :: Char) $
291 Prelude.take 50 $ Prelude.enumFrom f
293enumerateFromThenSmallBounded :: Property
294enumerateFromThenSmallBounded =
295 property
296 $ \f th ->
297 let unf = UF.take 50 UF.enumerateFromThenSmallBounded
298 in testUnfold unf (f :: Char, th) $
299 Prelude.take 50 $ Prelude.enumFromThen f th
301enumerateFromToSmall :: Property
302enumerateFromToSmall =
303 property
304 $ \f to ->
305 let unf = UF.take 50 UF.enumerateFromToSmall
306 in testUnfold unf (f :: Char, to) $
307 Prelude.take 50 $ Prelude.enumFromTo f to
309enumerateFromThenToSmall :: Property
310enumerateFromThenToSmall =
311 property
312 $ \f th to ->
313 let unf = UF.take 50 UF.enumerateFromThenToSmall
314 in testUnfold unf (f :: Char, th, to) $
315 Prelude.take 50 $ Prelude.enumFromThenTo f th to
317enumerateFromSmallBoundedOrd :: Property
318enumerateFromSmallBoundedOrd =
319 property
320 $ \f ->
321 let unf = UF.take 3 UF.enumerateFromSmallBounded
322 in testUnfold unf (f :: Ordering) $
323 Prelude.take 3 $ Prelude.enumFrom f
325enumerateFromThenSmallBoundedOrd :: Property
326enumerateFromThenSmallBoundedOrd =
327 property
328 $ \f th ->
329 let unf = UF.take 3 UF.enumerateFromThenSmallBounded
330 in testUnfold unf (f :: Ordering, th) $
331 Prelude.take 3 $ Prelude.enumFromThen f th
333enumerateFromToSmallOrd :: Property
334enumerateFromToSmallOrd =
335 property
336 $ \f to ->
337 let unf = UF.take 3 UF.enumerateFromToSmall
338 in testUnfold unf (f :: Ordering, to) $
339 Prelude.take 3 $ Prelude.enumFromTo f to
341enumerateFromThenToSmallOrd :: Property
342enumerateFromThenToSmallOrd =
343 property
344 $ \f th to ->
345 let unf = UF.take 3 UF.enumerateFromThenToSmall
346 in testUnfold unf (f :: Ordering, th, to) $
347 Prelude.take 3 $ Prelude.enumFromThenTo f th to
349-------------------------------------------------------------------------------
350enumerateFromSmallBoundedBool :: Property
351enumerateFromSmallBoundedBool =
352 property
353 $ \f ->
354 let unf = UF.take 2 UF.enumerateFromSmallBounded
355 in testUnfold unf (f :: Bool) $
356 Prelude.take 2 $ Prelude.enumFrom f
358enumerateFromThenSmallBoundedBool :: Property
359enumerateFromThenSmallBoundedBool =
360 property
361 $ \f th ->
362 let unf = UF.take 2 UF.enumerateFromThenSmallBounded
363 in testUnfold unf (f :: Bool, th) $
364 Prelude.take 2 $ Prelude.enumFromThen f th
366enumerateFromToSmallBool :: Property
367enumerateFromToSmallBool =
368 property
369 $ \f to ->
370 let unf = UF.take 2 UF.enumerateFromToSmall
371 in testUnfold unf (f :: Bool, to) $
372 Prelude.take 2 $ Prelude.enumFromTo f to
374enumerateFromThenToSmallBool :: Property
375enumerateFromThenToSmallBool =
376 property
377 $ \f th to ->
378 let unf = UF.take 2 UF.enumerateFromThenToSmall
379 in testUnfold unf (f :: Bool, th, to) $
380 Prelude.take 2 $ Prelude.enumFromThenTo f th to
381-------------------------------------------------------------------------------
382enumerateFromSmallBoundedUnit :: Property
383enumerateFromSmallBoundedUnit =
384 property
385 $ \f ->
386 let unf = UF.take 1 UF.enumerateFromSmallBounded
387 in testUnfold unf (f :: ()) $
388 Prelude.take 1 $ Prelude.enumFrom f
390enumerateFromThenSmallBoundedUnit :: Property
391enumerateFromThenSmallBoundedUnit =
392 property
393 $ \f th ->
394 let unf = UF.take 1 UF.enumerateFromThenSmallBounded
395 in testUnfold unf (f :: (), th) $
396 Prelude.take 1 $ Prelude.enumFromThen f th
398enumerateFromToSmallUnit :: Property
399enumerateFromToSmallUnit =
400 property
401 $ \f to ->
402 let unf = UF.take 1 UF.enumerateFromToSmall
403 in testUnfold unf (f :: (), to) $
404 Prelude.take 1 $ Prelude.enumFromTo f to
406enumerateFromThenToSmallUnit :: Property
407enumerateFromThenToSmallUnit =
408 property
409 $ \f th to ->
410 let unf = UF.take 1 UF.enumerateFromThenToSmall
411 in testUnfold unf (f :: (), th, to) $
412 Prelude.take 1 $ Prelude.enumFromThenTo f th to
415#if MIN_VERSION_base(4,12,0)
416enumerateFromFractional :: Property
417enumerateFromFractional =
418 property
419 $ \f ->
420 let unf = UF.take 50 UF.enumerateFromFractional
421 in testUnfold unf (f :: Double) $
422 Prelude.take 50 $ Prelude.enumFrom f
424enumerateFromThenFractional :: Property
425enumerateFromThenFractional =
426 property
427 $ \f th ->
428 let unf = UF.take 50 UF.enumerateFromThenFractional
429 in testUnfold unf (f :: Double, th) $
430 Prelude.take 50 $ Prelude.enumFromThen f th
432enumerateFromThenToFractional :: Property
433enumerateFromThenToFractional =
434 property
435 $ \f th to ->
436 let unf = UF.take 50 UF.enumerateFromThenToFractional
437 in testUnfold unf (f :: Double, th, to) $
438 Prelude.take 50 $ Prelude.enumFromThenTo f th to
440enumerateFromToFractional :: Property
441enumerateFromToFractional =
442 property
443 $ \f t ->
444 let unf = UF.enumerateFromToFractional
445 in testUnfold unf (f :: Double, t) [f..(t :: Double)]
447#endif
449-------------------------------------------------------------------------------
450-- Stream transformation
451-------------------------------------------------------------------------------
453postscan :: Property
454postscan =
455 property
456 $ \(ls :: [Int]) ->
457 let unf = UF.postscan Fold.sum UF.fromList
458 mList = scanl1 (+) ls
459 in testUnfold unf ls mList
461mapM :: Property
462mapM =
463 property
464 $ \f list ->
465 let fA = apply f :: Int -> Int
466 fM x = modify (+ 1) >> return (fA x)
467 unf = UF.mapM fM UF.fromList
468 mList = Prelude.map fA list
469 in testUnfoldMD unf list 0 (length list) mList
471mapMWithInput :: Property
472mapMWithInput =
473 property
474 $ \f list ->
475 let fA = applyFun2 f :: [Int] -> Int -> Int
476 fM x y = modify (+ 1) >> return (fA x y)
477 unf = UF.mapMWithInput fM UF.fromList
478 mList = Prelude.map (fA list) list
479 in testUnfoldMD unf list 0 (length list) mList
481take :: Property
482take =
483 property
484 $ \i ->
485 testUnfoldD
486 (UF.take i UF.repeatM)
487 (return 1)
488 (Prelude.take i (Prelude.repeat 1))
490takeWhileM :: Property
491takeWhileM =
492 property
493 $ \f list ->
494 let fM x =
495 if apply f x
496 then modify (+ 1) >> return True
497 else return False
498 unf = UF.takeWhileM fM UF.fromList
499 fL = Prelude.takeWhile (apply f) list
500 fS = Prelude.length fL
501 in testUnfoldMD unf list 0 fS fL
503filterM :: Property
504filterM =
505 property
506 $ \f list ->
507 let fM x =
508 if apply f x
509 then modify (+ 1) >> return True
510 else return False
511 unf = UF.filterM fM UF.fromList
512 fL = Prelude.filter (apply f) list
513 fS = Prelude.length fL
514 in testUnfoldMD unf list 0 fS fL
516drop :: Property
517drop =
518 property
519 $ \i list ->
520 let unf = UF.drop i UF.fromList
521 fL = Prelude.drop i list
522 in testUnfoldD unf list fL
524dropWhileM :: Property
525dropWhileM =
526 property
527 $ \f list ->
528 let fM x =
529 if apply f x
530 then modify (+ 1) >> return True
531 else return False
532 unf = UF.dropWhileM fM UF.fromList
533 fL = Prelude.dropWhile (apply f) list
534 fS = Prelude.length list - Prelude.length fL
535 in testUnfoldMD unf list 0 fS fL
537-------------------------------------------------------------------------------
538-- Stream combination
539-------------------------------------------------------------------------------
541zipWithM :: Property
542zipWithM =
543 property
544 $ \f ->
545 let unf1 = UF.enumerateFromToIntegral
546 unf2 = UF.enumerateFromToIntegral
547 fA = applyFun2 f :: Int -> Int -> Int
548 fM a b = modify (+ 1) >> return (fA a b)
549 unf = UF.zipWithM fM (UF.lmap fst unf1) (UF.lmap snd unf2)
550 lst = Prelude.zipWith fA [1 .. 10] [1 .. 20]
551 in testUnfoldMD unf ((1,10), (1,20)) 0 10 lst
553concat :: Bool
554concat =
555 let unfIn = UF.replicateM 10
556 unfOut = UF.map return UF.enumerateFromToIntegral
557 unf = UF.many unfIn unfOut
558 lst = Prelude.concat $ Prelude.map (Prelude.replicate 10) [1 .. 10]
559 in testUnfoldD unf (1, 10) lst
561outerProduct :: Bool
562outerProduct =
563 let unf1 = UF.enumerateFromToIntegral
564 unf2 = UF.enumerateFromToIntegral
565 unf = crossProduct unf1 unf2
566 lst = [(a, b) :: (Int, Int) | a <- [0 .. 10], b <- [0 .. 20]]
567 in testUnfold unf (((0,10) ,(0,20)) :: ((Int, Int), (Int, Int))) lst
569 where
571 crossProduct u1 u2 = UF.cross (UF.lmap fst u1) (UF.lmap snd u2)
573concatMapM :: Bool
574concatMapM =
575 let inner b =
576 let u = UF.lmap (\_ -> modify (+ 1) >> return b) (UF.replicateM 10)
577 in modify (+ 1) >> return u
578 unf = UF.concatMapM inner UF.enumerateFromToIntegral
579 list = List.concatMap (replicate 10) [1 .. 10]
580 in testUnfoldMD unf (1, 10) 0 110 list
582-------------------------------------------------------------------------------
583-- Test groups
584-------------------------------------------------------------------------------
586testInputOps :: Spec
587testInputOps =
588 describe "Input"
589 $ do
590 -- prop "lmap" lmap
591 prop "lmapM" lmapM
592 prop "both" both
593 prop "first" first
594 prop "second" second
595 prop "discardFirst" discardFirst
596 prop "discardSecond" discardSecond
597 prop "swap" swap
599testGeneration :: Spec
600testGeneration =
601 describe "Generation"
602 $ do
603 prop "fromStream" fromStream
604 prop "fromStreamK" fromStreamK
605 prop "fromStreamD" fromStreamD
606 prop "nilM" nilM
607 prop "consM" consM
608 prop "functionM" functionM
609 -- prop "function" function
610 -- prop "identity" identity
611 prop "const" const
612 prop "unfoldrM" unfoldrM
613 -- prop "fromList" fromList
614 prop "fromListM" fromListM
615 -- prop "fromSVar" fromSVar
616 -- prop "fromProducer" fromProducer
617 prop "replicateM" replicateM
618 prop "repeatM" repeatM
619 prop "iterateM" iterateM
620 prop "fromIndicesM" fromIndicesM
621 ----------- Enumerate from Num ------------------------------------
622 prop "enumerateFromNum" enumerateFromNum
623 prop "enumerateFromThenNum" enumerateFromThenNum
624 ----------- Enumerate from Integral -------------------------------
625 prop "enumerateFromIntegral" enumerateFromIntegral
626 prop "enumerateFromThenIntegral" enumerateFromThenIntegral
627 prop "enumerateFromToIntegral" enumerateFromToIntegral
628 prop "enumerateFromThenToIntegral" enumerateFromThenToIntegral
630 prop "enumerateFromIntegralBounded" enumerateFromIntegralBounded
631 prop "enumerateFromThenIntegralBounded" enumerateFromThenIntegralBounded
632 prop "enumerateFromToIntegralBounded" enumerateFromToIntegralBounded
633 prop "enumerateFromThenToIntegralBounded" enumerateFromThenToIntegralBounded
634 ----------- Enumerate from Small Integral -------------------------
635 prop "enumerateFromSmallBounded" enumerateFromSmallBounded
636 prop "enumerateFromThenSmallBounded" enumerateFromThenSmallBounded
637 prop "enumerateFromToSmall" enumerateFromToSmall
638 prop "enumerateFromThenToSmall" enumerateFromThenToSmall
639 --
640 prop "enumerateFromSmallBoundedOrd" enumerateFromSmallBoundedOrd
641 prop "enumerateFromThenSmallBoundedOrd" enumerateFromThenSmallBoundedOrd
642 prop "enumerateFromToSmallOrd" enumerateFromToSmallOrd
643 prop "enumerateFromThenToSmallOrd" enumerateFromThenToSmallOrd
645 prop "enumerateFromSmallBoundedUnit" enumerateFromSmallBoundedUnit
646 prop "enumerateFromThenSmallBoundedUnit" enumerateFromThenSmallBoundedUnit
647 prop "enumerateFromToSmallUnit" enumerateFromToSmallUnit
648 prop "enumerateFromThenToSmallUnit" enumerateFromThenToSmallUnit
650 prop "enumerateFromSmallBoundedUnit" enumerateFromSmallBoundedBool
651 prop "enumerateFromThenSmallBoundedBool" enumerateFromThenSmallBoundedBool
652 prop "enumerateFromToSmallBool" enumerateFromToSmallBool
653 prop "enumerateFromThenToSmallBool" enumerateFromThenToSmallBool
655#if MIN_VERSION_base(4,12,0)
656 prop "enumerateFromFractional" enumerateFromFractional
657 prop "enumerateFromThenFractional" enumerateFromThenFractional
658 prop "enumerateFromToFractional" enumerateFromToFractional
659 prop "enumerateFromThenToFractional" enumerateFromThenToFractional
660#endif
662testTransformation :: Spec
663testTransformation =
664 describe "Transformation"
665 $ do
666 -- prop "map" map
667 prop "postscan" postscan
668 prop "mapM" mapM
669 prop "mapMWithInput" mapMWithInput
670 prop "takeWhileM" takeWhileM
671 -- prop "takeWhile" takeWhile
672 prop "take" take
673 -- prop "filter" filter
674 prop "filterM" filterM
675 prop "drop" drop
676 -- prop "dropWhile" dropWhile
677 prop "dropWhileM" dropWhileM
679testCombination :: Spec
680testCombination =
681 describe "Transformation"
682 $ do
683 prop "zipWithM" zipWithM
684 -- prop "zipWith" zipWith
685 -- prop "teeZipWith" teeZipWith
686 prop "concat" concat
687 prop "concatMapM" concatMapM
688 prop "outerProduct" outerProduct
689 -- prop "ap" ap
690 -- prop "apDiscardFst" apDiscardFst
691 -- prop "apDiscardSnd" apDiscardSnd
693-------------------------------------------------------------------------------
694-- Main
695-------------------------------------------------------------------------------
697moduleName :: String
698moduleName = "Data.Unfold"
700main :: IO ()
701main =
702 hspec
703 $ describe moduleName
704 $ do
705 testInputOps
706 testGeneration
707 testTransformation
708 testCombination