Skip to content

Commit 2dde880

Browse files
committed
Add strictness tests for Map construction
1 parent fbade40 commit 2dde880

File tree

3 files changed

+1299
-8
lines changed

3 files changed

+1299
-8
lines changed

containers-tests/containers-tests.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ test-suite map-strictness-properties
403403

404404
other-modules:
405405
Utils.IsUnit
406+
Utils.Strictness
406407

407408
if impl(ghc >= 8.6)
408409
build-depends:
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
module Utils.Strictness
2+
( Bot(..)
3+
, Func(..)
4+
, applyFunc
5+
, Func2(..)
6+
, applyFunc2
7+
, Func3(..)
8+
, applyFunc3
9+
) where
10+
11+
import Test.ChasingBottoms.IsBottom (isBottom)
12+
import Test.QuickCheck
13+
14+
{--------------------------------------------------------------------
15+
Bottom stuff
16+
--------------------------------------------------------------------}
17+
18+
-- | Arbitrary (Bot a) values may be bottom
19+
newtype Bot a = Bot a
20+
21+
instance Show a => Show (Bot a) where
22+
show (Bot x) = if isBottom x then "<bottom>" else show x
23+
24+
instance Arbitrary a => Arbitrary (Bot a) where
25+
arbitrary = frequency
26+
[ (1, pure (error "<bottom>"))
27+
, (4, Bot <$> arbitrary)
28+
]
29+
30+
{--------------------------------------------------------------------
31+
Lazy functions
32+
--------------------------------------------------------------------}
33+
34+
-- | Function which may be lazy in its argument
35+
data Func a b
36+
= FuncLazy b
37+
| FuncStrict (Fun a b)
38+
39+
instance (Show a, Show b) => Show (Func a b) where
40+
show (FuncLazy x) = "{_lazy->" ++ show x ++ "}"
41+
show (FuncStrict fun) = show fun
42+
43+
applyFunc :: Func a b -> a -> b
44+
applyFunc fun x = case fun of
45+
FuncLazy y -> y
46+
FuncStrict f -> applyFun f x
47+
48+
instance (CoArbitrary a, Function a, Arbitrary b) => Arbitrary (Func a b) where
49+
arbitrary = frequency
50+
[ (1, FuncLazy <$> arbitrary)
51+
, (4, FuncStrict <$> arbitrary)
52+
]
53+
54+
shrink fun = case fun of
55+
FuncLazy x -> FuncLazy <$> shrink x
56+
FuncStrict f -> FuncStrict <$> shrink f
57+
58+
-- | Function which may be lazy in its arguments
59+
data Func2 a b c
60+
= F2A (Func a (Func b c))
61+
| F2B (Func b (Func a c))
62+
deriving Show
63+
64+
instance
65+
(CoArbitrary a, Function a, CoArbitrary b, Function b, Arbitrary c)
66+
=> Arbitrary (Func2 a b c) where
67+
arbitrary = oneof [F2A <$> arbitrary, F2B <$> arbitrary]
68+
69+
shrink fun2 = case fun2 of
70+
F2A fun -> F2A <$> shrink fun
71+
F2B fun -> F2B <$> shrink fun
72+
73+
applyFunc2 :: Func2 a b c -> a -> b -> c
74+
applyFunc2 fun2 x y = case fun2 of
75+
F2A fun -> applyFunc (applyFunc fun x) y
76+
F2B fun -> applyFunc (applyFunc fun y) x
77+
78+
-- | Function which may be lazy in its arguments
79+
data Func3 a b c d
80+
= F3A (Func a (Func2 b c d))
81+
| F3B (Func b (Func2 a c d))
82+
| F3C (Func c (Func2 a b d))
83+
deriving Show
84+
85+
instance
86+
( CoArbitrary a, Function a
87+
, CoArbitrary b, Function b
88+
, CoArbitrary c, Function c
89+
, Arbitrary d
90+
)
91+
=> Arbitrary (Func3 a b c d) where
92+
arbitrary = oneof [F3A <$> arbitrary, F3B <$> arbitrary, F3C <$> arbitrary]
93+
94+
shrink fun3 = case fun3 of
95+
F3A fun -> F3A <$> shrink fun
96+
F3B fun -> F3B <$> shrink fun
97+
F3C fun -> F3C <$> shrink fun
98+
99+
applyFunc3 :: Func3 a b c d -> a -> b -> c -> d
100+
applyFunc3 fun3 x y z = case fun3 of
101+
F3A fun -> applyFunc2 (applyFunc fun x) y z
102+
F3B fun -> applyFunc2 (applyFunc fun y) x z
103+
F3C fun -> applyFunc2 (applyFunc fun z) x y

0 commit comments

Comments
 (0)