@@ -21,6 +21,7 @@ import Control.Applicative (Applicative(..), liftA2)
2121import Control.Arrow ((***) )
2222import Control.Monad.Trans.State.Strict
2323import Data.Array (listArray )
24+ import Data.Coerce (coerce )
2425import Data.Foldable (Foldable (foldl , foldl1 , foldr , foldr1 , foldMap , fold ), toList , all , sum , foldl' , foldr' )
2526import Data.Functor ((<$>) , (<$) )
2627import Data.Maybe
@@ -43,8 +44,10 @@ import Control.Monad.Zip (MonadZip (..))
4344import Control.DeepSeq (deepseq )
4445import Control.Monad.Fix (MonadFix (.. ))
4546import Test.Tasty.HUnit
47+ import Test.ChasingBottoms.IsBottom (isBottom )
4648import qualified Language.Haskell.TH.Syntax as TH
4749
50+ import Utils.Strictness (Bot (.. ), Func2 , applyFunc2 )
4851
4952main :: IO ()
5053main = defaultMain $ testGroup " seq-properties"
@@ -56,11 +59,9 @@ main = defaultMain $ testGroup "seq-properties"
5659 , testProperty " (<$)" prop_constmap
5760 , testProperty " foldr" prop_foldr
5861 , testProperty " foldr'" prop_foldr'
59- , testProperty " lazy foldr'" prop_lazyfoldr'
6062 , testProperty " foldr1" prop_foldr1
6163 , testProperty " foldl" prop_foldl
6264 , testProperty " foldl'" prop_foldl'
63- , testProperty " lazy foldl'" prop_lazyfoldl'
6465 , testProperty " foldl1" prop_foldl1
6566 , testProperty " (==)" prop_equals
6667 , testProperty " compare" prop_compare
@@ -156,6 +157,12 @@ main = defaultMain $ testGroup "seq-properties"
156157 , testProperty " Right view pattern" prop_viewr_pat
157158 , testProperty " Right view constructor" prop_viewr_con
158159 , testProperty " stimes" prop_stimes
160+ , testGroup " strictness"
161+ [ testProperty " foldr" prop_strictness_foldr
162+ , testProperty " foldl" prop_strictness_foldl
163+ , testProperty " foldr'" prop_strictness_foldr'
164+ , testProperty " foldl'" prop_strictness_foldl'
165+ ]
159166 ]
160167
161168------------------------------------------------------------------------
@@ -310,16 +317,6 @@ prop_foldr' xs =
310317 f = (:)
311318 z = []
312319
313- prop_lazyfoldr' :: Seq () -> Property
314- prop_lazyfoldr' xs =
315- not (null xs) ==>
316- foldr'
317- (\ e _ ->
318- e)
319- (error " Data.Sequence.foldr': should be lazy in initial accumulator" )
320- xs ===
321- ()
322-
323320prop_foldr1 :: Seq Int -> Property
324321prop_foldr1 xs =
325322 not (null xs) ==> foldr1 f xs == Data.List. foldr1 f (toList xs)
@@ -339,16 +336,6 @@ prop_foldl' xs =
339336 f = flip (:)
340337 z = []
341338
342- prop_lazyfoldl' :: Seq () -> Property
343- prop_lazyfoldl' xs =
344- not (null xs) ==>
345- foldl'
346- (\ _ e ->
347- e)
348- (error " Data.Sequence.foldl': should be lazy in initial accumulator" )
349- xs ===
350- ()
351-
352339prop_foldl1 :: Seq Int -> Property
353340prop_foldl1 xs =
354341 not (null xs) ==> foldl1 f xs == Data.List. foldl1 f (toList xs)
@@ -903,6 +890,42 @@ test_mfix = toList resS === resL
903890 resL :: [Int ]
904891 resL = fmap ($ 12 ) $ mfix (\ f -> [facty f, facty (+ 1 ), facty (+ 2 )])
905892
893+ -- * Strictness tests
894+
895+ -- See Note [Testing strictness of folds] in map-strictness.hs
896+
897+ prop_strictness_foldr :: [A ] -> Func2 A B (Bot B ) -> Bot B -> Property
898+ prop_strictness_foldr xs fun (Bot z) =
899+ isBottom (foldr f z s) ===
900+ isBottom (foldr f z xs)
901+ where
902+ s = fromList xs
903+ f = coerce (applyFunc2 fun) :: A -> B -> B
904+
905+ prop_strictness_foldl :: [A ] -> Func2 B A (Bot B ) -> Bot B -> Property
906+ prop_strictness_foldl (xs) fun (Bot z) =
907+ isBottom (foldl f z s) ===
908+ isBottom (foldl f z xs)
909+ where
910+ s = fromList xs
911+ f = coerce (applyFunc2 fun) :: B -> A -> B
912+
913+ prop_strictness_foldr' :: [A ] -> Func2 A B (Bot B ) -> Bot B -> Property
914+ prop_strictness_foldr' xs fun (Bot z) =
915+ isBottom (foldr' f z s) ===
916+ isBottom (z `seq` foldr' f z xs)
917+ where
918+ s = fromList xs
919+ f = coerce (applyFunc2 fun) :: A -> B -> B
920+
921+ prop_strictness_foldl' :: [A ] -> Func2 B A (Bot B ) -> Bot B -> Property
922+ prop_strictness_foldl' xs fun (Bot z) =
923+ isBottom (foldl' f z s) ===
924+ isBottom (foldl' f z xs)
925+ where
926+ s = fromList xs
927+ f = coerce (applyFunc2 fun) :: B -> A -> B
928+
906929-- Simple test monad
907930
908931data M a = Action Int a
0 commit comments