简体   繁体   中英

Defining division using Haskell

I decided it would be cool to learn Haskell by recreating arithmetic using only the Succ function, or other functions I've defined, and the Integer number type. So far I've managed to (re)create Add, Subtract, and Multiply, only for Integers. I've created a predecessor function as well.

However, I want division over rational numbers, but I don't want to borrow anymore types. What I'd like to do is use a pair of Integers to define the numerator and denominator and work from there. What's cool is that if I figure this out, the complex plane and operations on it should be a similar.

(I know that using the Integer type is technically cheating, and that I don't need it. But if I do fancy things like Peano arithmetic (?) I also have to figure out how get the system to represent the solution with pretty digits and the like. )

How would I define a custom "rational" number type as a pair of two Integers?

I'd go about it like so, the traditional inductive way:

data N = Z | S N deriving (Show, Eq)
cmp Z Z = EQ -- of course, could have derived Ord
cmp Z _ = LT
cmp (S _) Z = GT
cmp (S x) (S y) = cmp x y

add Z x = x
add (S x) y = S $ add x y

sub Z x = Z -- have to do something to negative numbers
sub x Z = x
sub (S x) (S y) = sub x y

divi x y | cmp x y == LT = (x, Z)
divi x y = fmap S $ divi (sub x y) y -- dividing by Z will not terminate

Then we have

Prelude> divi (S $ S $ S Z) (S $ S Z)  -- 3 / 2 == (1,1)
(S Z,S Z)
Prelude> divi (S $ S $ S $ S Z) (S $ S Z)  -- 4 / 2 == (0, 2)
(Z,S (S Z))

for some background on how to encode integer arithmetic in rewriting (and you can easily translate this into first-order functional programs), see

Walters and Zantema, Rewrite Systems for Integer Arithmetic, http://www.cs.uu.nl/research/techreps/repo/CS-1994/1994-43.pdf

Contejean, Marche, Rabehasaina, Rewrite Systems for natural, integer, and rational Arithmetic, https://www.lri.fr/~marche/articles/rta97.ps.gz

and references cited there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM