-
Notifications
You must be signed in to change notification settings - Fork 1
/
Inf.hs
56 lines (48 loc) · 1.76 KB
/
Inf.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
---------
-- Inf --
---------
module Inf
( Inf
, inf, fin
) where
data Inf a
= Finite a
| Infinite Bool
deriving Eq
instance Show a => Show (Inf a) where
show (Finite x) = show x
show (Infinite True ) = "<+inf>"
show (Infinite False) = "<-inf>"
instance Ord a => Ord (Inf a) where
compare (Finite x ) (Finite y) = compare x y
compare (Infinite b ) (Infinite c) = compare b c
compare (Infinite True ) _ = GT
compare (Infinite False) _ = LT
compare _ (Infinite True ) = LT
compare _ (Infinite False) = GT
instance (Num a, Eq a) => Num (Inf a) where
Finite x + Finite y = Finite (x + y)
Infinite True + Infinite False = error "<+inf> + <-inf>"
Infinite False + Infinite True = error "<-inf> + <+inf>"
Infinite True + _ = Infinite True
Infinite False + _ = Infinite False
_ + Infinite True = Infinite True
_ + Infinite False = Infinite False
Finite x * Finite y = Finite (x * y)
Infinite b * Infinite c = Infinite (b == c)
Infinite _ * Finite 0 = error "<inf> * 0"
Finite 0 * Infinite _ = error "0 * <inf>"
Infinite b * Finite x = Infinite (b == (signum x == 1))
Finite x * Infinite b = Infinite ((signum x == 1) == b)
negate (Infinite b ) = Infinite (not b)
negate (Finite x ) = Finite (negate x)
signum (Infinite True ) = 1
signum (Infinite False) = -1
signum (Finite x ) = Finite (signum x)
abs (Infinite _ ) = Infinite True
abs (Finite x ) = Finite (abs x)
fromInteger x = Finite (fromInteger x)
fin :: a -> Inf a
fin = Finite
inf :: Inf a
inf = Infinite True