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