-
Notifications
You must be signed in to change notification settings - Fork 0
/
Rational.idr
51 lines (37 loc) · 1.74 KB
/
Rational.idr
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
module Rational
-- TODONOTE there is no rational class
-- TODONOTE could use a type class, but whatever
data Rational : Type where
MkRational : Integer -> (d : Integer) -> ((d == 0) = False) -> Rational
quotRem : Integer -> Integer -> (Integer, Integer)
quotRem n d = (div n d, mod n d)
numerator : Rational -> Integer
numerator (MkRational x d prf) = x
denominator : Rational -> Integer
denominator (MkRational x d prf) = d
{- TODONOTE elemIndex is confused about (Int vs Integer), there's no cast tho?
-}
decF : Integer -> Integer -> List (Integer,Integer) -> (List Integer, List Integer)
decF n d xs = let (q,r) = quotRem n d
xs' = reverse xs
(Just k) = elemIndex (q,r) xs'
(ys,zs) = splitAt k (map fst xs') in
if r == 0 then (reverse (q :: (map fst xs)),[]) else
if elem (q,r) xs then (ys,zs) else
decF (r*10) d ((q,r)::xs)
-- TODONOTE handle x < 0 error
decForm : Rational -> (Integer,List Integer, List Integer)
decForm x = let
n = numerator x
d = denominator x
(q,r) = quotRem n d
(ys,zs) = decF (r*10) d [] in
(q, ys, zs)
recip : Rational -> Rational
recip (MkRational x d prf) = case x == 0 of
True => MkRational 0 1 Refl
False => MkRational d x ?pfInverse
rationalMult : Rational -> Rational -> Rational
rationalMult (MkRational x d prf) (MkRational y z w) = MkRational (x*y) (d*z) ?pfMult
rationalAdd : Rational -> Rational -> Rational
rationalAdd (MkRational x y p1) (MkRational n m p2) = MkRational (m*x + n*y) (m*y) ?pfAdd