| 1 | {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, ScopedTypeVariables #-} |
|---|
| 2 | {-# LANGUAGE UndecidableInstances #-} |
|---|
| 3 | {- |
|---|
| 4 | - |
|---|
| 5 | - Copyright 2005-2006, Robert Dockins. |
|---|
| 6 | - |
|---|
| 7 | -} |
|---|
| 8 | |
|---|
| 9 | {- | This module defines type-level natural numbers and arithmetic operation on them |
|---|
| 10 | including addition, subtraction, multiplication, division and GCD. |
|---|
| 11 | |
|---|
| 12 | Numbers are represented as a list of binary digits, terminated by a distinguished type 'Z'. |
|---|
| 13 | Least significant digits are outermost, which makes the numbers little-endian when read. |
|---|
| 14 | |
|---|
| 15 | Because a binary representation is used, reasonably large numbers can be |
|---|
| 16 | represented. I have personally done tests with numbers at the order |
|---|
| 17 | of 10^15 in GHC. However, larger numbers require the GHC \'-fcontext-stack\' option. |
|---|
| 18 | For example, the test suite sets \'-fcontext-stack64\'. |
|---|
| 19 | |
|---|
| 20 | Because of the limitations of typeclasses, some of the algorithms are pretty |
|---|
| 21 | messy. The division algorithm is particularly ugly. Suggestions for improvements |
|---|
| 22 | are welcome. |
|---|
| 23 | -} |
|---|
| 24 | |
|---|
| 25 | module TypeNats2 where |
|---|
| 26 | |
|---|
| 27 | -- | Terminates a list of binary digits with an imagined infinity of zeros. |
|---|
| 28 | data Z |
|---|
| 29 | |
|---|
| 30 | -- | A zero bit. |
|---|
| 31 | data O a |
|---|
| 32 | |
|---|
| 33 | -- | A one bit. |
|---|
| 34 | data I a -- a one bit |
|---|
| 35 | |
|---|
| 36 | type Zero = Z |
|---|
| 37 | type One = (I Z) |
|---|
| 38 | type Two = (O (I Z)) |
|---|
| 39 | type Three = (I (I Z)) |
|---|
| 40 | type Four = (O (O (I Z))) |
|---|
| 41 | type Five = (I (O (I Z))) |
|---|
| 42 | type Six = (O (I (I Z))) |
|---|
| 43 | type Seven = (I (I (I Z))) |
|---|
| 44 | type Eight = (O (O (O (I Z)))) |
|---|
| 45 | type Nine = (I (O (O (I Z)))) |
|---|
| 46 | type Ten = (O (I (O (I Z)))) |
|---|
| 47 | type Eleven = (I (I (O (I Z)))) |
|---|
| 48 | type Twelve = (O (O (I (I Z)))) |
|---|
| 49 | type Thirteen = (I (O (I (I Z)))) |
|---|
| 50 | type Fourteen = (O (I (I (I Z)))) |
|---|
| 51 | type Fifteen = (I (I (I (I Z)))) |
|---|
| 52 | type Sixteen = (O (O (O (O (I Z))))) |
|---|
| 53 | type Seventeen = (I (O (O (O (I Z))))) |
|---|
| 54 | type Eighteen = (O (I (O (O (I Z))))) |
|---|
| 55 | type Nineteen = (I (I (O (O (I Z))))) |
|---|
| 56 | |
|---|
| 57 | type Twenty = (O (O (I (O (I Z))))) |
|---|
| 58 | type Thirty = (O (I (O (I (I Z))))) |
|---|
| 59 | type Fourty = (O (O (O (I (O (I Z)))))) |
|---|
| 60 | type Fifty = (O (I (O (O (I (I Z)))))) |
|---|
| 61 | type Sixty = (O (O (I (I (I (I Z)))))) |
|---|
| 62 | type Seventy = (O (I (I (O (O (O (I Z))))))) |
|---|
| 63 | type Eighty = (O (O (O (O (I (O (I Z))))))) |
|---|
| 64 | type Ninety = (O (I (O (I (I (O (I Z))))))) |
|---|
| 65 | type Hundred = (O (O (I (O (O (I (I Z))))))) |
|---|
| 66 | |
|---|
| 67 | -- Hexidecimal digits |
|---|
| 68 | type Ox0 a = (O (O (O (O a)))) |
|---|
| 69 | type Ox1 a = (I (O (O (O a)))) |
|---|
| 70 | type Ox2 a = (O (I (O (O a)))) |
|---|
| 71 | type Ox3 a = (I (I (O (O a)))) |
|---|
| 72 | type Ox4 a = (O (O (I (O a)))) |
|---|
| 73 | type Ox5 a = (I (O (I (O a)))) |
|---|
| 74 | type Ox6 a = (O (I (I (O a)))) |
|---|
| 75 | type Ox7 a = (I (I (I (O a)))) |
|---|
| 76 | type Ox8 a = (O (O (O (I a)))) |
|---|
| 77 | type Ox9 a = (I (O (O (I a)))) |
|---|
| 78 | type Oxa a = (O (I (O (I a)))) |
|---|
| 79 | type Oxb a = (I (I (O (I a)))) |
|---|
| 80 | type Oxc a = (O (O (I (I a)))) |
|---|
| 81 | type Oxd a = (I (O (I (I a)))) |
|---|
| 82 | type Oxe a = (O (I (I (I a)))) |
|---|
| 83 | type Oxf a = (I (I (I (I a)))) |
|---|
| 84 | |
|---|
| 85 | -- some larger numbers |
|---|
| 86 | type Thousand = Ox8 (Oxe (Ox3 Z)) |
|---|
| 87 | type Million = Ox0 (Ox4 (Ox2 (Ox4 (Oxf Z)))) |
|---|
| 88 | type Billion = Ox0 (Ox0 (Oxa (Oxc (Oxa (Ox9 (Oxb (Ox3 Z))))))) |
|---|
| 89 | |
|---|
| 90 | -- | The Natural class, with conversion to intergral values. |
|---|
| 91 | -- The conversion should be linear in the number of bits, which |
|---|
| 92 | -- is logarithmic in the magnitute of the number. |
|---|
| 93 | |
|---|
| 94 | class Natural a where |
|---|
| 95 | naturalToIntegral :: Integral b => a -> b |
|---|
| 96 | |
|---|
| 97 | instance Natural Z where |
|---|
| 98 | naturalToIntegral _ = fromInteger 0 |
|---|
| 99 | |
|---|
| 100 | instance Natural a => Natural (O a) where |
|---|
| 101 | naturalToIntegral _ = let x = naturalToIntegral (undefined::a) in x+x |
|---|
| 102 | |
|---|
| 103 | instance Natural a => Natural (I a) where |
|---|
| 104 | naturalToIntegral _ = let x = naturalToIntegral (undefined::a) in succ (x+x) |
|---|
| 105 | |
|---|
| 106 | -- | Zero predicate. Zero is represented by a single 'Z' or |
|---|
| 107 | -- a string of 'O' terminated by 'Z'. |
|---|
| 108 | class IsZero a |
|---|
| 109 | instance IsZero Z |
|---|
| 110 | instance IsZero a => IsZero (O a) |
|---|
| 111 | |
|---|
| 112 | -- | The equality relation on nats. |
|---|
| 113 | class EqNat a b |
|---|
| 114 | instance (IsZero a) => EqNat a Z |
|---|
| 115 | instance (EqNat Z b) => EqNat Z (O b) |
|---|
| 116 | instance (EqNat a b) => EqNat (O a) (O b) |
|---|
| 117 | instance (EqNat a b) => EqNat (I a) (I b) |
|---|
| 118 | |
|---|
| 119 | -- | The successor function; defined for all naturals. |
|---|
| 120 | class (Natural a, Natural b) => NatSucc a b | a -> b |
|---|
| 121 | instance NatSucc Z (I Z) |
|---|
| 122 | instance Natural a => NatSucc (O a) (I a) |
|---|
| 123 | instance NatSucc a b => NatSucc (I a) (O b) |
|---|
| 124 | |
|---|
| 125 | natSucc :: (NatSucc a b) => a -> b |
|---|
| 126 | natSucc = undefined |
|---|
| 127 | |
|---|
| 128 | -- | The predecessor function; not defined for zero. |
|---|
| 129 | class (Natural a, Natural b) => NatPred a b | a -> b |
|---|
| 130 | instance Natural a => NatPred (I a) (O a) |
|---|
| 131 | instance NatPred a b => NatPred (O a) (I b) |
|---|
| 132 | |
|---|
| 133 | natPred :: NatPred a b => a -> b |
|---|
| 134 | natPred = undefined |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | -- | Binary addition. This is a pretty basic full adder. |
|---|
| 138 | -- The 'AddC' class represents add with carry. |
|---|
| 139 | -- Addition is defined for all pairs of natural numbers. |
|---|
| 140 | |
|---|
| 141 | class (Natural a,Natural b,Natural c) => Add a b c | a b -> c |
|---|
| 142 | instance Add Z Z Z |
|---|
| 143 | instance (Natural a) => Add Z (O a) (O a) |
|---|
| 144 | instance (Natural a) => Add Z (I a) (I a) |
|---|
| 145 | instance (Natural a) => Add (O a) Z (O a) |
|---|
| 146 | instance (Natural a) => Add (I a) Z (I a) |
|---|
| 147 | |
|---|
| 148 | instance Add a b c => Add (O a) (O b) (O c) |
|---|
| 149 | instance Add a b c => Add (I a) (O b) (I c) |
|---|
| 150 | instance Add a b c => Add (O a) (I b) (I c) |
|---|
| 151 | instance AddC a b c => Add (I a) (I b) (O c) |
|---|
| 152 | |
|---|
| 153 | class (Natural a,Natural b,Natural c) => AddC a b c | a b -> c |
|---|
| 154 | instance AddC Z Z (I Z) |
|---|
| 155 | instance Natural a => AddC Z (O a) (I a) |
|---|
| 156 | instance NatSucc a b => AddC Z (I a) (O b) |
|---|
| 157 | instance Natural a => AddC (O a) Z (I a) |
|---|
| 158 | instance NatSucc a b => AddC (I a) Z (O b) |
|---|
| 159 | |
|---|
| 160 | instance Add a b c => AddC (O a) (O b) (I c) |
|---|
| 161 | instance AddC a b c => AddC (I a) (O b) (O c) |
|---|
| 162 | instance AddC a b c => AddC (O a) (I b) (O c) |
|---|
| 163 | instance AddC a b c => AddC (I a) (I b) (I c) |
|---|
| 164 | |
|---|
| 165 | add :: Add a b c => a -> b -> c |
|---|
| 166 | add = undefined |
|---|
| 167 | |
|---|
| 168 | |
|---|
| 169 | |
|---|
| 170 | |
|---|
| 171 | -- | A distinguished error type which is returned when |
|---|
| 172 | -- subtraction is impossible. |
|---|
| 173 | data CantSubtract |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | -- | Binary subtraction. Slightly less elegant than the adder but it works. |
|---|
| 177 | -- 'DoSub' returns a distingushed error type if a < b and '()' if the subtraction suceeds. |
|---|
| 178 | |
|---|
| 179 | class (Natural a, Natural b) => Sub a b c | a b -> c |
|---|
| 180 | instance DoSub a b c () => Sub a b c |
|---|
| 181 | |
|---|
| 182 | class (Natural a, Natural b) => DoSub a b c d | a b -> c d |
|---|
| 183 | instance Natural a => DoSub a Z a () |
|---|
| 184 | instance DoSub Z b c d => DoSub Z (O b) c d -- this rule does not loop, because |
|---|
| 185 | -- the b parameter is decreasing |
|---|
| 186 | instance Natural b => DoSub Z (I b) () CantSubtract |
|---|
| 187 | |
|---|
| 188 | instance DoSub a b c d => DoSub (O a) (O b) (O c) d |
|---|
| 189 | instance DoSub a b c d => DoSub (I a) (O b) (I c) d |
|---|
| 190 | instance DoSub a b c d => DoSub (I a) (I b) (O c) d |
|---|
| 191 | instance SubBorrow b c a z z d => DoSub (O a) (I b) (I c) d |
|---|
| 192 | |
|---|
| 193 | sub :: Sub a b c => a -> b -> c |
|---|
| 194 | sub = undefined |
|---|
| 195 | |
|---|
| 196 | -- this is tricky, we use the top level call to SubBorrow |
|---|
| 197 | -- to unify the final result with z, so that is is avaliable |
|---|
| 198 | -- when we want to call Sub again |
|---|
| 199 | class (Natural b,Natural x) => SubBorrow b c x y z d | x z b -> c d, x -> y |
|---|
| 200 | |
|---|
| 201 | instance Natural b => SubBorrow b () Z () z CantSubtract |
|---|
| 202 | instance (Natural x,DoSub z b c d) => SubBorrow b c (I x) (O x) z d |
|---|
| 203 | instance SubBorrow b c x y z d => SubBorrow b c (O x) (I y) z d |
|---|
| 204 | |
|---|
| 205 | {- |
|---|
| 206 | how we used to do it. This way can't return the distinguished |
|---|
| 207 | CantSubtract type when borrowing fails. We need that distinguisged |
|---|
| 208 | type in order to do the tests we need for division and GCD |
|---|
| 209 | |
|---|
| 210 | instance (Borrow a a',Sub a' b c) => Sub (O a) (I b) (I c) |
|---|
| 211 | |
|---|
| 212 | class Borrow a b | a -> b |
|---|
| 213 | instance Borrow (I a) (O a) |
|---|
| 214 | instance Borrow a b => Borrow (O a) (I b) |
|---|
| 215 | -} |
|---|
| 216 | |
|---|
| 217 | |
|---|
| 218 | class Trichotomy n m lt eq gt z | n m lt eq gt -> z |
|---|
| 219 | instance (DoSub n m p a, DoSub m n q b, DoTrichotomy a b lt eq gt z) => Trichotomy n m lt eq gt z |
|---|
| 220 | |
|---|
| 221 | class DoTrichotomy a b lt eq gt z | a b lt eq gt -> z |
|---|
| 222 | instance DoTrichotomy CantSubtract () lt eq gt lt |
|---|
| 223 | instance DoTrichotomy () () lt eq gt eq |
|---|
| 224 | instance DoTrichotomy () CantSubtract lt eq gt gt |
|---|
| 225 | |
|---|
| 226 | |
|---|
| 227 | -- comparison relations on naturals, defined |
|---|
| 228 | -- in terms of subtraction |
|---|
| 229 | |
|---|
| 230 | -- | The less-than-or-equal-to relation |
|---|
| 231 | class LEqNat a b |
|---|
| 232 | instance (DoSub b a c ()) => LEqNat a b |
|---|
| 233 | |
|---|
| 234 | -- | The greater-than-or-equal-to relation |
|---|
| 235 | class GEqNat a b |
|---|
| 236 | instance (DoSub a b c ()) => GEqNat a b |
|---|
| 237 | |
|---|
| 238 | -- | The less-than relation |
|---|
| 239 | class LTNat a b |
|---|
| 240 | instance (DoSub a b c CantSubtract) => LTNat a b |
|---|
| 241 | |
|---|
| 242 | -- | The greater-than relation |
|---|
| 243 | class GTNat a b |
|---|
| 244 | instance (DoSub b a c CantSubtract) => GTNat a b |
|---|
| 245 | |
|---|
| 246 | |
|---|
| 247 | -- | Binary multiplication. This is a |
|---|
| 248 | -- simple shift and add peasant multiplier. |
|---|
| 249 | |
|---|
| 250 | class Mul a b c | a b -> c |
|---|
| 251 | instance Mul a Z Z |
|---|
| 252 | instance (Mul (O a) b x) => Mul a (O b) x |
|---|
| 253 | instance (Mul (O a) b c,Add a c x) => Mul a (I b) x |
|---|
| 254 | |
|---|
| 255 | mul :: Mul a b c => a -> b -> c |
|---|
| 256 | mul = undefined |
|---|
| 257 | |
|---|
| 258 | |
|---|
| 259 | |
|---|
| 260 | |
|---|
| 261 | -- | Division by 2. |
|---|
| 262 | -- This is real easy, just throw away the outermost |
|---|
| 263 | -- type constructor. |
|---|
| 264 | |
|---|
| 265 | class (Natural a,Natural b) => Div2 a b | a -> b |
|---|
| 266 | instance Div2 Z Z |
|---|
| 267 | instance Natural a => Div2 (O a) a |
|---|
| 268 | instance Natural a => Div2 (I a) a |
|---|
| 269 | |
|---|
| 270 | div2 :: Div2 a b => a -> b |
|---|
| 271 | div2 = undefined |
|---|
| 272 | |
|---|
| 273 | |
|---|
| 274 | -- | Normalize a nat; that is, remove all leading zeros. |
|---|
| 275 | |
|---|
| 276 | class NatNormalize a b | a -> b |
|---|
| 277 | |
|---|
| 278 | instance (NatRev a Z c |
|---|
| 279 | ,NatNorm c c' |
|---|
| 280 | ,NatRev c' Z a' |
|---|
| 281 | ) |
|---|
| 282 | => NatNormalize a a' |
|---|
| 283 | |
|---|
| 284 | class NatRev a b c | a b -> c |
|---|
| 285 | instance NatRev Z b b |
|---|
| 286 | instance NatRev a (O b) c => NatRev (O a) b c |
|---|
| 287 | instance NatRev a (I b) c => NatRev (I a) b c |
|---|
| 288 | |
|---|
| 289 | class NatNorm a b | a -> b |
|---|
| 290 | instance NatNorm Z Z |
|---|
| 291 | instance NatNorm (I a) (I a) |
|---|
| 292 | instance NatNorm a b => NatNorm (O a) b |
|---|
| 293 | |
|---|
| 294 | |
|---|
| 295 | normalize :: NatNormalize a b => a -> b |
|---|
| 296 | normalize = undefined |
|---|
| 297 | |
|---|
| 298 | |
|---|
| 299 | |
|---|
| 300 | -- | A distinguished error type returned when |
|---|
| 301 | -- attempting to divide by zero. |
|---|
| 302 | data DivideByZero |
|---|
| 303 | |
|---|
| 304 | -- | Binary division and modulus. This one is suprisingly difficult to implement. |
|---|
| 305 | class DivMod a d q r | a d -> q r |
|---|
| 306 | instance ( NatRev a Z a' |
|---|
| 307 | , NatRev d Z d' |
|---|
| 308 | , PreDivMod a' d' (q,r) |
|---|
| 309 | ) => DivMod a d q r |
|---|
| 310 | |
|---|
| 311 | -- here we throw away leading zeros and test for |
|---|
| 312 | -- a zero divisor |
|---|
| 313 | class PreDivMod a d z | a d -> z |
|---|
| 314 | instance PreDivMod Z d z => PreDivMod Z (O d) z |
|---|
| 315 | instance PreDivMod a d z => PreDivMod (O a) (O d) z |
|---|
| 316 | instance PreDivMod (I a) d z => PreDivMod (I a) (O d) z |
|---|
| 317 | instance PreDivMod a (I d) z => PreDivMod (O a) (I d) z |
|---|
| 318 | instance PreDivMod2 Z (I d) Z Z z => PreDivMod Z (I d) z |
|---|
| 319 | instance PreDivMod2 (I a) (I d) Z Z z => PreDivMod (I a) (I d) z |
|---|
| 320 | instance PreDivMod a Z DivideByZero |
|---|
| 321 | |
|---|
| 322 | -- now we begin to "unreverse" until all the divisor |
|---|
| 323 | -- digits are in the correct order |
|---|
| 324 | class PreDivMod2 a w d r z | a w d r -> z |
|---|
| 325 | instance PreDivMod2 Z w (O d) r z => PreDivMod2 Z (O w) d r z |
|---|
| 326 | instance PreDivMod2 a w (O d) (O r) z => PreDivMod2 (O a) (O w) d r z |
|---|
| 327 | instance PreDivMod2 a w (O d) (I r) z => PreDivMod2 (I a) (O w) d r z |
|---|
| 328 | instance PreDivMod2 Z w (I d) r z => PreDivMod2 Z (I w) d r z |
|---|
| 329 | instance PreDivMod2 a w (I d) (O r) z => PreDivMod2 (O a) (I w) d r z |
|---|
| 330 | instance PreDivMod2 a w (I d) (I r) z => PreDivMod2 (I a) (I w) d r z |
|---|
| 331 | instance DoDivMod a d Z r z => PreDivMod2 a Z d r z |
|---|
| 332 | |
|---|
| 333 | -- now we do binary long division |
|---|
| 334 | -- first we do case analysis on the |
|---|
| 335 | -- remining dividend, then case analysis |
|---|
| 336 | -- on the difference between the current |
|---|
| 337 | -- remainder and the dividend.... |
|---|
| 338 | |
|---|
| 339 | class DoDivMod a d q r z | a d q r -> z |
|---|
| 340 | instance ( DoSub r d x err |
|---|
| 341 | , DoDivModZ err x q r z |
|---|
| 342 | ) => DoDivMod Z d q r z |
|---|
| 343 | |
|---|
| 344 | instance ( DoSub r d x err |
|---|
| 345 | , DoDivModO err x a d q r z |
|---|
| 346 | ) => DoDivMod (O a) d q r z |
|---|
| 347 | |
|---|
| 348 | instance ( DoSub r d x err |
|---|
| 349 | , DoDivModI err x a d q r z |
|---|
| 350 | ) => DoDivMod (I a) d q r z |
|---|
| 351 | |
|---|
| 352 | |
|---|
| 353 | class DoDivModZ err x q r z | err x q r -> z |
|---|
| 354 | instance DoDivModZ () Z q r (I q,r) |
|---|
| 355 | instance DoDivModZ () (O x) q r (I q,O x) |
|---|
| 356 | instance DoDivModZ () (I x) q r (I q,I x) |
|---|
| 357 | instance DoDivModZ CantSubtract x q r (O q,r) |
|---|
| 358 | |
|---|
| 359 | class DoDivModO err x a d q r z | err x a d q r -> z |
|---|
| 360 | instance DoDivMod a d (I q) Z z => DoDivModO () Z a d q r z |
|---|
| 361 | instance DoDivMod a d (I q) (O (O x)) z => DoDivModO () (O x) a d q r z |
|---|
| 362 | instance DoDivMod a d (I q) (O (I x)) z => DoDivModO () (I x) a d q r z |
|---|
| 363 | instance DoDivMod a d (O q) (O r) z => DoDivModO CantSubtract x a d q r z |
|---|
| 364 | |
|---|
| 365 | class DoDivModI err x a d q r z | err x a d q r -> z |
|---|
| 366 | instance DoDivMod a d (I q) (I Z) z => DoDivModI () Z a d q r z |
|---|
| 367 | instance DoDivMod a d (I q) (I (O x)) z => DoDivModI () (O x) a d q r z |
|---|
| 368 | instance DoDivMod a d (I q) (I (I x)) z => DoDivModI () (I x) a d q r z |
|---|
| 369 | instance DoDivMod a d (O q) (I r) z => DoDivModI CantSubtract x a d q r z |
|---|
| 370 | |
|---|
| 371 | |
|---|
| 372 | natDivMod :: DivMod a b q r => a -> b -> (q,r) |
|---|
| 373 | natDiv :: DivMod a b q r => a -> b -> q |
|---|
| 374 | natMod :: DivMod a b q r => a -> b -> r |
|---|
| 375 | |
|---|
| 376 | natDivMod = undefined |
|---|
| 377 | natDiv = undefined |
|---|
| 378 | natMod = undefined |
|---|
| 379 | |
|---|
| 380 | |
|---|
| 381 | -- | A distinguished error type returned when |
|---|
| 382 | -- an attempt is made to take the GCD of 0 and 0. |
|---|
| 383 | data GCDZeroZero |
|---|
| 384 | |
|---|
| 385 | -- | Greatest Common Divisor (GCD). |
|---|
| 386 | -- Here we use the binary euclidian algorithm. |
|---|
| 387 | |
|---|
| 388 | -- there is a little fancy dancing to with DoGCD2 |
|---|
| 389 | -- in order to replace the largest argument with |
|---|
| 390 | -- their difference |
|---|
| 391 | |
|---|
| 392 | class GCD a b c | a b -> c |
|---|
| 393 | instance ( NatNormalize a a' |
|---|
| 394 | , NatNormalize b b' |
|---|
| 395 | , DoGCD a' b' c |
|---|
| 396 | ) => GCD a b c |
|---|
| 397 | |
|---|
| 398 | class DoGCD a b c | a b -> c |
|---|
| 399 | instance DoGCD Z Z GCDZeroZero |
|---|
| 400 | instance DoGCD (O a) Z (O a) |
|---|
| 401 | instance DoGCD (I a) Z (I a) |
|---|
| 402 | instance DoGCD Z (O a) (O a) |
|---|
| 403 | instance DoGCD Z (I a) (I a) |
|---|
| 404 | instance DoGCD a b c => DoGCD (O a) (O b) (O c) |
|---|
| 405 | instance DoGCD a (I b) c => DoGCD (O a) (I b) c |
|---|
| 406 | instance DoGCD (I a) b c => DoGCD (I a) (O b) c |
|---|
| 407 | |
|---|
| 408 | -- in this branch we want to replace the largest argument with |
|---|
| 409 | -- the absolute value of their difference. All this nastyness |
|---|
| 410 | -- is necessary to be able to figure out which one is bigger and |
|---|
| 411 | -- subtract the correct way. |
|---|
| 412 | |
|---|
| 413 | instance (DoSub a b x1 f1 |
|---|
| 414 | ,DoSub b a x2 f2 |
|---|
| 415 | ,DoGCD2 x1 x2 f1 f2 |
|---|
| 416 | (I a) (I b) c) => DoGCD (I a) (I b) c |
|---|
| 417 | |
|---|
| 418 | |
|---|
| 419 | class DoGCD2 x1 x2 f1 f2 a b c | x1 x2 f1 f2 a b -> c |
|---|
| 420 | |
|---|
| 421 | -- handle GCD(x,x) case. x and y must be (possibly distinct) representations of zero |
|---|
| 422 | instance (IsZero x,IsZero y) => DoGCD2 x y () () a b a |
|---|
| 423 | |
|---|
| 424 | -- replace the larger with the difference |
|---|
| 425 | instance DoGCD (O x1) b c => DoGCD2 x1 x2 () CantSubtract a b c |
|---|
| 426 | instance DoGCD a (O x2) c => DoGCD2 x1 x2 CantSubtract () a b c |
|---|
| 427 | |
|---|
| 428 | |
|---|
| 429 | natGCD :: GCD a b c => a -> b -> c |
|---|
| 430 | natGCD = undefined |
|---|
| 431 | |
|---|
| 432 | |
|---|
| 433 | |
|---|
| 434 | -- define a bunch of useful naturals |
|---|
| 435 | |
|---|
| 436 | zero :: Zero |
|---|
| 437 | one :: One |
|---|
| 438 | two :: Two |
|---|
| 439 | three :: Three |
|---|
| 440 | four :: Four |
|---|
| 441 | five :: Five |
|---|
| 442 | six :: Six |
|---|
| 443 | seven :: Seven |
|---|
| 444 | eight :: Eight |
|---|
| 445 | nine :: Nine |
|---|
| 446 | ten :: Ten |
|---|
| 447 | eleven :: Eleven |
|---|
| 448 | twelve :: Twelve |
|---|
| 449 | thirteen :: Thirteen |
|---|
| 450 | fourteen :: Fourteen |
|---|
| 451 | fifteen :: Fifteen |
|---|
| 452 | sixteen :: Sixteen |
|---|
| 453 | seventeen :: Seventeen |
|---|
| 454 | eighteen :: Eighteen |
|---|
| 455 | nineteen :: Nineteen |
|---|
| 456 | |
|---|
| 457 | twenty :: Add Twenty b c => b -> c |
|---|
| 458 | twenty_ :: Twenty |
|---|
| 459 | thirty :: Add Thirty b c => b -> c |
|---|
| 460 | thirty_ :: Thirty |
|---|
| 461 | fourty :: Add Fourty b c => b -> c |
|---|
| 462 | fourty_ :: Fourty |
|---|
| 463 | fifty :: Add Fifty b c => b -> c |
|---|
| 464 | fifty_ :: Fifty |
|---|
| 465 | sixty :: Add Sixty b c => b -> c |
|---|
| 466 | sixty_ :: Sixty |
|---|
| 467 | seventy :: Add Seventy b c => b -> c |
|---|
| 468 | seventy_ :: Seventy |
|---|
| 469 | eighty :: Add Eighty b c => b -> c |
|---|
| 470 | eighty_ :: Eighty |
|---|
| 471 | ninety :: Add Ninety b c => b -> c |
|---|
| 472 | ninety_ :: Ninety |
|---|
| 473 | |
|---|
| 474 | hundred :: (Mul Hundred a b,Add b x y) => a -> x -> y |
|---|
| 475 | thousand :: (Mul Thousand a b,Add b x y) => a -> x -> y |
|---|
| 476 | million :: (Mul Million a b,Add b x y) => a -> x -> y |
|---|
| 477 | billion :: (Mul Billion a b,Add b x y) => a -> x -> y |
|---|
| 478 | |
|---|
| 479 | infixr 5 `billion` |
|---|
| 480 | infixr 5 `million` |
|---|
| 481 | infixr 5 `thousand` |
|---|
| 482 | infix 6 `hundred` |
|---|
| 483 | |
|---|
| 484 | zero = undefined |
|---|
| 485 | one = undefined |
|---|
| 486 | two = undefined |
|---|
| 487 | three = undefined |
|---|
| 488 | four = undefined |
|---|
| 489 | five = undefined |
|---|
| 490 | six = undefined |
|---|
| 491 | seven = undefined |
|---|
| 492 | eight = undefined |
|---|
| 493 | nine = undefined |
|---|
| 494 | ten = undefined |
|---|
| 495 | eleven = undefined |
|---|
| 496 | twelve = undefined |
|---|
| 497 | thirteen = undefined |
|---|
| 498 | fourteen = undefined |
|---|
| 499 | fifteen = undefined |
|---|
| 500 | sixteen = undefined |
|---|
| 501 | seventeen = undefined |
|---|
| 502 | eighteen = undefined |
|---|
| 503 | nineteen = undefined |
|---|
| 504 | |
|---|
| 505 | twenty = undefined |
|---|
| 506 | thirty = undefined |
|---|
| 507 | fourty = undefined |
|---|
| 508 | fifty = undefined |
|---|
| 509 | sixty = undefined |
|---|
| 510 | seventy = undefined |
|---|
| 511 | eighty = undefined |
|---|
| 512 | ninety = undefined |
|---|
| 513 | twenty_ = undefined |
|---|
| 514 | thirty_ = undefined |
|---|
| 515 | fourty_ = undefined |
|---|
| 516 | fifty_ = undefined |
|---|
| 517 | sixty_ = undefined |
|---|
| 518 | seventy_ = undefined |
|---|
| 519 | eighty_ = undefined |
|---|
| 520 | ninety_ = undefined |
|---|
| 521 | |
|---|
| 522 | hundred = undefined |
|---|
| 523 | thousand = undefined |
|---|
| 524 | million = undefined |
|---|
| 525 | billion = undefined |
|---|