-
Notifications
You must be signed in to change notification settings - Fork 3
/
Chapter3.hs
162 lines (107 loc) · 3.48 KB
/
Chapter3.hs
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
------------------------------------------------------------------------------
--
-- Haskell: The Craft of Functional Programming, 3e
-- Simon Thompson
-- (c) Addison-Wesley, 1996-2011.
--
-- Chapter 3
--
------------------------------------------------------------------------------
module Chapter3 where
import Prelude hiding (max)
import Test.QuickCheck
-- The import statement which follows hides certain of the Prelude functions
-- so that they can be given the definitions they have in their book.
-- The Booleans.
-- ^^^^^^^^^^^^^
-- Exclusive or: this gives the result True if one of its arguments is True and
-- the other False, and gives the result False in other cases.
exOr :: Bool -> Bool -> Bool
exOr x y = (x || y) && not (x && y)
-- Using literals instead of variables in a definition; a simple example of
-- pattern matching to give another definition of `not', ...
myNot :: Bool -> Bool
myNot True = False
myNot False = True
prop_myNot :: Bool -> Bool
prop_myNot x =
not x == myNot x
-- ... and of `exclusive or'.
exOr1 True x = not x
exOr1 False x = x
-- Test exOrs
prop_exOrs :: Bool -> Bool -> Bool
prop_exOrs x y =
exOr x y == exOr1 x y
prop_exOr2 :: Bool -> Bool -> Bool
prop_exOr2 x y =
exOr x y == (x /= y)
-- Integers and guards.
-- ^^^^^^^^^^^^^^^^^^^^
-- A to test whether three Ints are equal.
threeEqual :: Integer -> Integer -> Integer -> Bool
threeEqual m n p = (m==n) && (n==p)
-- The maximum of two integers; this is already defined in the Prelude,
-- so its definition is hidden by the import statement at the top of this file.
max :: Integer -> Integer -> Integer
max x y
| x >= y = x
| otherwise = y
-- The maximum of three integers.
maxThree :: Integer -> Integer -> Integer -> Integer
maxThree x y z
| (x >= y) && (x >= z) = x
| y >= z = y
| otherwise = z
-- An alternative definition of max which uses if ... then ... else ...
max' :: Integer -> Integer -> Integer
max' x y
= if x >= y then x else y
prop_compareMax :: Integer -> Integer -> Bool
prop_compareMax x y =
max x y == max' x y
prop_max1, prop_max2, prop_max3 :: Integer -> Integer -> Bool
prop_max1 x y =
x <= max x y && y <= max x y
prop_max2 x y =
x == max x y || y == max x y
prop_max3 x y =
(x == max x y) `exOr` (y == max x y)
-- Characters.
-- ^^^^^^^^^^^
-- Converting lower-case letters to upper-case; does something odd if you apply
-- it to anythig else: how would you modify it to return anything else
-- unchanged?
toUpper :: Char -> Char
toUpper ch = toEnum (fromEnum ch + offset)
offset = fromEnum 'A' - fromEnum 'a'
-- A check whether a character is a digit.
isDigit :: Char -> Bool
isDigit ch = ('0' <= ch) && (ch <= '9')
-- The String type
-- ^^^^^^^^^^^^^^^
-- Example strings
str1, str2, str3, str4, str5 :: String
str1 = "baboon"
str2 = ""
str3 = "\99a\116"
str4 = "gorilla\nhippo\nibex"
str5 = "1\t23\t456"
pstr1, pstr2, pstr3, pstr4, pstr5 :: IO ()
pstr1 = putStr str1
pstr2 = putStr str2
pstr3 = putStr str3
pstr4 = putStr str4
pstr5 = putStr str5
-- Some syntax.
-- ^^^^^^^^^^^^
-- Layout: two definitions on one line, separated by a `;'.
answer = 42 ; facSix = 720
-- Adding two integers: you can use longer names for variables than x and y!
addTwo :: Integer -> Integer -> Integer
addTwo first second = first+second
-- Defining an operator for yourself: another version of max!
(&&&) :: Integer -> Integer -> Integer
x &&& y
| x > y = y
| otherwise = x