1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
-- $Id: arith003.hs,v 1.2 2002/01/25 13:40:39 simonmar Exp $
--
-- !!! test Int/Integer arithmetic operations from the Prelude.
--
main
= putStr
(
showit (do_ops int_ops) ++
showit (do_ops integer_ops)
)
showit :: Integral a => [(String, a, a, a)] -> String
showit stuff = concat
[ str ++ " " ++ show l ++ " " ++ show r ++ " = " ++ show result ++ "\n"
| (str, l, r, result) <- stuff
]
do_ops :: Integral a => [((a -> a -> a), String, [(a,a)])]
-> [(String, a, a, a)]
do_ops ops = [ (str, l, r, l `op` r) | (op,str,args) <- ops, (l,r) <- args ]
small_operands, non_min_operands, operands, non_max_operands
:: Integral a => [a]
small_operands = [ 0, 1, -1, 2, -2 ]
operands = small_operands ++ [ fromIntegral minInt, fromIntegral maxInt ]
non_min_operands = small_operands ++ [ fromIntegral maxInt ]
non_max_operands = small_operands ++ [ fromIntegral minInt ]
large_operands :: [ Integer ]
large_operands = operands ++
[ fromIntegral minInt - 1,
fromIntegral maxInt + 1,
fromIntegral minInt * 2,
fromIntegral maxInt * 2,
fromIntegral minInt ^ 2,
fromIntegral maxInt ^ 2
]
integer_ops :: [((Integer -> Integer -> Integer), String, [(Integer,Integer)])]
integer_ops = [
((+), "(+)", both_large),
((-), "(-)", both_large),
(div, "div", large_non_zero_r),
(mod, "mod", large_non_zero_r),
(quot, "quot", large_non_zero_r),
(rem, "rem", large_non_zero_r),
(gcd, "gcd", large_either_non_zero),
(lcm, "lcm", large_either_non_zero)
]
int_ops :: [((Int -> Int -> Int), String, [(Int,Int)])]
int_ops = [
((+), "(+)", both_small),
((-), "(-)", both_small),
((^), "(^)", small_non_neg_r),
(div, "div", non_min_l_or_zero_r),
(mod, "mod", non_min_l_or_zero_r),
(quot, "quot", non_min_l_or_zero_r),
(rem, "rem", non_min_l_or_zero_r),
(gcd, "gcd", non_min_either_non_zero),
(lcm, "lcm", non_max_r_either_non_zero)
]
-- NOTE: when abs(minInt) is undefined (it is in GHC, because
-- abs(minInt) would be greater than maxInt), then gcd on Ints is also
-- undefined when either operand is minInt.
both_small, non_zero_r, non_min_either_non_zero, non_min_l_or_zero_r,
non_max_r_either_non_zero, small_non_neg_r
:: Integral a => [(a,a)]
both_small = [ (l,r) | l <- operands, r <- operands ]
both_large = [ (l,r) | l <- large_operands, r <- large_operands ]
large_non_zero_r = [ (l,r) | l <- operands, r <- large_operands, r /= 0 ]
non_zero_r = [ (l,r) | l <- operands, r <- operands, r /= 0 ]
non_min_either_non_zero = [ (l,r) | l <- non_min_operands, r <- non_min_operands, l /= 0 || r /= 0 ]
large_either_non_zero = [ (l,r) | l <- operands, r <- operands, l /= 0 || r /= 0 ]
small_non_neg_r = [ (l,r) | l <- operands, r <- small_operands, r >= 0 ]
non_min_l_or_zero_r = [ (l,r) | l <- non_min_operands, r <- operands, r /= 0 ]
non_max_r_either_non_zero = [ (l,r) | l <- operands, r <- non_max_operands, l /= 0 || r /= 0 ]
minInt = minBound :: Int
maxInt = maxBound :: Int
|