-
Notifications
You must be signed in to change notification settings - Fork 3
/
Chapter_13_my_note.hs
366 lines (293 loc) · 11.6 KB
/
Chapter_13_my_note.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
{-# OPTIONS_GHC -XFlexibleContexts #-}
{-# OPTIONS_GHC -XFlexibleInstances #-}
module Chapter_13_my_note where
import Chapter_5_my_note ( Shape ( Circle
, Rectangle
, Triangle )
, area
, circulation
, isRound )
import Chapter_7_my_note (isSorted)
listMatch :: Eq a => [a] -> a -> Bool
listMatch ls val = all (== val) ls
numEqual :: Eq a => [a] -> a -> Int
numEqual xs x = length (filter (== x) xs)
oneLookupFirst :: Eq a => [(a, b)] -> a -> b
oneLookupFirst xs vala = (head . map snd . filter (\(x, _) -> x == vala)) xs
oneLookupSecond :: Eq b => [(a, b)] -> b -> a
oneLookupSecond xs valb = (head . map fst . filter (\(_, y) -> y == valb)) xs
class Info a where
example :: [a]
example = []
size :: a -> Int
size _ = 1
provideExp :: a -> [a]
provideExp _ = example
instance Info Bool where
example = [True, False]
instance Info Char where
example = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['0' .. '9']
instance Info Int where
example = [-100 .. 100]
instance Info Float where
example = [3.0, 45.9, 87.6]
instance Info Shape where
example = [ Circle (head (example :: [Float]))
, Rectangle ((example :: [Float]) !! 1) ((example :: [Float]) !! 2) ]
size = round . area
instance Info a => Info [a] where
example = [[]] ++ [[x] | x <- example] ++ [[x, y] | x <- example, y <- example]
size = foldr ((+) . size) 0
instance (Info a, Info b) => Info (a, b) where
example = [(_a, _b) | _a <- example, _b <- example]
size (va, vb) = size va + size vb
class Equ a where
(===), (/==) :: a -> a -> Bool
x /== y = not (x === y)
x === y = not (x /== y)
instance Equ Integer where
x === y = x == y
-- x /== y = x == y
-- I know how it is defined here.
-- define one side and accomplish two sides
class (Ord a, Show a) => OrdShow a
instance OrdShow Char
instance OrdShow Integer
instance OrdShow Float
instance OrdShow Int
insert :: Ord a => [a] -> a -> [a]
insert ls targ = [x | x <- ls, x < targ] ++ [targ] ++ [x | x <- ls, x >= targ]
iSort :: Ord a => [a] -> [a]
iSort = foldr (flip insert) []
vSort :: OrdShow a => [a] -> String
vSort = show . iSort
class Checkable b where
infoCheck :: (Info a) => (a -> b) -> Bool
instance Checkable Bool where
infoCheck property = all property example
instance (Info a, Checkable b) => Checkable (a -> b) where
infoCheck property = all (infoCheck . property) example
data Move = Paper | Stone | Scissors
deriving Eq
instance Show Move where
show Paper = "paper"
show Stone = "stone"
show Scissors = "scissors"
data Suit = Spade | Heart | Diamond | Club
deriving Eq
instance Show Suit where
show Spade = "spade"
show Heart = "heart"
show Diamond = "diamond"
show Club = "club"
data Value = One | Two | Three | Four | Five | Six |
Seven | Eight | Nine | Ten | Jack | Queen |
King | Ace
deriving (Eq, Ord)
instance Show Value where
show One = "one"
show Two = "two"
show Three = "three"
show Four = "four"
show Five = "five"
show Six = "six"
show Seven = "seven"
show Eight = "eight"
show Nine = "nine"
show Ten = "ten"
show Jack = "jack"
show Queen = "queen"
show King = "king"
show Ace = "ace"
data Card = CardConstruct Suit Value
deriving Eq
instance Show Card where
show (CardConstruct suit val) = show suit ++ " " ++ show val
data Trip = MakeTrip { a :: Int
, b :: Int
, c :: Int }
deriving Eq
instance Show Trip where
show (MakeTrip _a _b _c) = "(" ++ show _a ++ ", "
++ show _b ++ ", "
++ show _c ++ ")"
class (Show a) => Visible a where
visualize :: a -> String
visualize = show
instance Visible Int
instance Visible Float
instance Visible Bool
instance Visible Char where
visualize v = [v]
instance (Visible a) => Visible [a] where
visualize [] = ""
visualize (x : xs) = visualize x ++ concatMap ((" " ++) . visualize) xs
instance (Info a, Info b, Info c, Visible a, Visible b, Visible c) => Visible (a, b, c) where
visualize (_a, _b, _c) = "(" ++ visualize _a
++ ", " ++ visualize _b
++ ", " ++ visualize _c ++ ")"
instance Info (Int -> Bool) where
example = [(== 1)]
size _ = 1
instance Info (Int -> Int) where
example = [id]
size _ = 1
infoCompare :: (Info a, Info b) => a -> b -> Bool
infoCompare _a _b = size _a <= size _b
class Eq a => Order a where
(-<), (>-), (-<=), (=>-) :: a -> a -> Bool
a1 -< a2 = a2 >- a1
a1 >- a2 = a2 -< a1
a1 -<= a2 = a2 =>- a1
a1 =>- a2 = a2 -<= a1
_max, _min :: a -> a -> a
_max a1 a2 = if a1 >- a2 then a1 else a2
_min a1 a2 = if a1 >- a2 then a2 else a1
_compare :: a -> a -> Ordering
_compare a1 a2
| a1 >- a2 = GT
| a1 == a2 = EQ
| otherwise = LT
instance (Order a, Order b) => Order (a, b) where
(a1, b1) -< (a2, b2)
| a1 -< a2 = True
| a1 == a2 && b1 -< b2 = True
| otherwise = False
_max (a1, b1) (a2, b2)
| (a1, b1) -< (a2, b2) = (a1, b1)
| otherwise = (a2, b2)
_min (a1, b1) (a2, b2)
| (a1, b1) >- (a2, b2) = (a1, b1)
| otherwise = (a2, b2)
instance Order a => Order [a] where
_ -< [] = False
[] -< (_ : _) = True
(_a : lsa) -< (_b : lsb)
| _a -< _b = True
| _a == _b = lsa -< lsb
| otherwise = False
_max lsa lsb
| lsa -< lsb = lsb
| otherwise = lsa
_min lsa lsb
| lsa -< lsb = lsa
| otherwise = lsb
instance Order Char where (-<) = (<)
instance Order Int where (-<) = (<)
instance Order Float where (-<) = (<)
instance Order Bool where (-<) = (<)
class Ord a => Enumerate a where
esucc, epred :: a -> a
toEnumerate :: Int -> a
fromEnumerate :: a -> Int
enumerateFrom :: a -> [a]
enumerateFromThen :: a -> a -> [a]
enumerateFromTo :: a -> a -> [a]
enumerateFromThenTo :: a -> a -> a -> [a]
instance Enumerate Int where
esucc = succ
epred = pred
fromEnumerate = fromEnum
toEnumerate = toEnumerate
enumerateFrom val = [val ..]
enumerateFromThen val nxt = [val, nxt ..]
enumerateFromTo val fin = [val .. fin]
enumerateFromThenTo val nxt fin = [val, nxt .. fin]
instance Enumerate Integer where
esucc = succ
epred = pred
fromEnumerate = fromEnum
toEnumerate = toEnumerate
enumerateFrom val = [val ..]
enumerateFromThen val nxt = [val, nxt ..]
enumerateFromTo val fin = [val .. fin]
enumerateFromThenTo val nxt fin = [val, nxt .. fin]
instance Enumerate Char where
esucc = succ
epred = pred
fromEnumerate = fromEnum
toEnumerate = toEnumerate
enumerateFrom val = [val ..]
enumerateFromThen val nxt = [val, nxt ..]
enumerateFromTo val fin = [val .. fin]
enumerateFromThenTo val nxt fin = [val, nxt .. fin]
data Boolean = True_ | False_
deriving (Eq, Show, Read)
-- https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Ord.html
-- fuck you asshole haskell
-- I used to have the idea about (a1 .. an) ord is automatic
-- then here I see it is just ... fuck...
-- instance Show (Bool -> Bool) where
-- show = showBoolFun
showBoolFun :: (Bool -> Bool) -> String
showBoolFun func = "Truth table\n------+------\n"
++ show True ++ " |" ++ (show . func) True ++ "\n"
++ show False ++ " |" ++ (show . func) False ++ "\n"
showBoolFunGen :: (a -> String) -> (Bool -> a) -> String
showBoolFunGen expr func = "Truth table\n------+------\n"
++ show True ++ " |" ++ (expr . func) True ++ "\n"
++ show False ++ " |" ++ (expr . func) False ++ "\n"
instance (Info a, Show a, Show b) => Show (a -> b) where
show func = concatMap (\x -> show x ++ " " ++ ((++ "\n") . show . func) x) example
class StrangeOrder a where
(<~) :: a -> a -> Bool
(~>) :: a -> a -> Bool
(<~) _ _ = False
(~>) _ _ = False
instance StrangeOrder Move where
data Roman = Roman Integer
instance Num Roman where
(Roman va) + (Roman vb) = Roman (va + vb)
(Roman va) - (Roman vb) = Roman (va - vb)
(Roman va) * (Roman vb) = Roman (va * vb)
instance Show Roman where
show (Roman val) = (if val < 0 then "(NEGATIVE) " else "")
++ valRoman convMap (abs val) []
filtRoman :: String -> String
filtRoman = filter (`elem` "MCDXLVIO")
splitRoman :: String -> [Integer]
splitRoman [] = []
splitRoman str = (fst . matchFir) str :
splitRoman (drop (length ((snd . matchFir) str)) str)
matchRomFir :: String -> [(Integer, String)]
matchRomFir str = map (\x -> if headsub (snd x) str then x else (-1, "")) convMap
matchFir :: String -> (Integer, String)
matchFir str = (head . filter (\x -> fst x == maxv) . matchRomFir) str
where maxv = (maximum . map fst . matchRomFir) str :: Integer
headsub :: String -> String -> Bool
headsub str1 str2 = if length str2 >= 2
then and (zipWith (==) str1 str2)
else str1 == str2
readroman :: String -> Roman
readroman str = if (isSorted . reverse) digarray
then Roman (sum digarray)
else error "wrong type roman value"
where digarray = (splitRoman . filtRoman) str :: [Integer]
convMap :: [(Integer, String)]
convMap = [ (1000, "M"), (900, "CM"), (500, "D"), (400, "CD")
, (100, "C"), (90, "XC"), (50, "L"), (40, "XL")
, (10, "X"), (9, "IX"), (5, "V"), (4, "IV")
, (1, "I"), (0, "O") ]
mapFindNext :: [(Integer, String)] -> Integer -> (Integer, String)
mapFindNext [] _ = error "empty list, error"
mapFindNext (s : ls) curr = if fst s <= curr then s else mapFindNext ls curr
valRoman :: [(Integer, String)] -> Integer -> String -> String
valRoman _ 0 [] = "O"
valRoman _ 0 wtf = wtf
valRoman vsp val str = valRoman convMap (val - eliminVal) (str ++ addingStr)
where addingPair = mapFindNext vsp val
addingStr = snd addingPair
eliminVal = fst addingPair
_multComp :: Ord a => a -> a -> Ordering
_multComp vala valb
| vala == valb = EQ
| vala > valb = GT
| otherwise = LT
_multMerge :: Ord a => [a] -> [a] -> [a]
_multMerge [] (y : ys) = y : ys
_multMerge (x : xs) [] = x : xs
_multMerge [] [] = []
_multMerge (x : xs) (y : ys)
| x < y = x : _multMerge xs (y : ys)
| x == y = x : y : _multMerge xs ys
| otherwise = y : _multMerge (x : xs) ys