Defining division using Haskell - 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.

Related

Haskell types/type conversion (sqrt,floor)

I'm trying to implement the Cantor Pairing using Haskell. The encoding of a list of ints is working fine, the decoding however is just not working due to type errors.
I tried nearly everything I could think of, but nothing would work out:
cantorDecode :: Integer -> [Integer] -> [Integer]
cantorDecode e zs
| length zs == 0 = cantorDecode y [x,y]
| head zs == 0 = map toInteger $ tail zs
| otherwise = cantorDecode y ((head zs)-1 : (tail zs) ++ [x,y])
where
a = fromRational e
w = floor ((s-1.0)/2.0)
s = fromIntegral $ sqrt(8.0*e+1.0) :: Double
t = fromRational $ (w^2+w)/2.0
y = toInteger $ e - (toInteger $ floor t)
x = toInteger $ (toInteger w) - (toInteger y)
input is the next Integer to decode
input is the list with the already decoded Integers
As you can see, I'm using sqrt, floor and other things, so it's a bit messy...
OK that does look desperate. A couple points:
You certainly don't want fromRational, since you have no actual Rationals here. Also, fromRational and toFractional are both strictly less general than their combination realToFrac, although you don't need that either - these are all for converting between different floating point/rational types, but you have only one involved, Double.
You don't want toInteger, which is only for converting between different Integral types. You do want its generalization fromIntegral which converts from an Integral type to a general Num.
You should make a clear decision exactly which of your variables are Integers, and which are Doubles. Then use fromIntegral to convert from Integer to Double, and floor or another similar function to convert from Double to Integer, when necessary. You have several attempts there to convert between the same type (basically, all your toIntegers.)
Given this, you can clean your type-conversion code up into (adding explicit type annotations for clarity):
cantorDecode :: Integer -> [Integer] -> [Integer]
cantorDecode e zs
| length zs == 0 = cantorDecode y [x,y]
| head zs == 0 = tail zs
| otherwise = cantorDecode y ((head zs)-1 : (tail zs) ++ [x,y])
where
w = floor ((s-1.0)/2.0) :: Integer
w' = fromIntegral w :: Double
s = sqrt(8.0*fromIntegral e+1.0) :: Double
t = (w'^2+w')/2.0 :: Double
y = e - floor t :: Integer
x = w - y :: Integer

Recursive functions with multiple arguments Haskell

A really simple question: I want to implement the multiplication of 2 integers in Haskell.
What I wrote doesn't compile:
mult :: Int -> Int -> Int
mult x 1 = x
mult 1 y = y
mult x y = x + (mult x-1 y)
The problem is the last statement. I've tried writing it as:
mult x y = x + (mult x-1 y)
and also
mult x y = x + (mult(x-1,y))
The error I get is:
Couldn't match expected type `Int' with actual type `Int -> Int'
In the return type of a call of `mult'
I don't know why the compiler would say that mult returns an Int -> Int when it clearly returns an Int.
You have to put x-1 into brackets! Like so
mult x y = x + (mult (x-1) y)
By the way, this does not compute the multiplication of x and y :-)
Try some examples... it's a little mistake only.
In
mult x y = x + (mult x-1 y)
the expression within the parentheses parses as:
(mult x) - (1 y)
And so the compiler thinks the first argument to (-) is mult x, which is an Int -> Int function because just one argument (rather than two) is being passed. Instead, you want:
mult x y = x + mult (x-1) y
It's a simple parser issue. The compiler is reading mult x-1 y as ((-) (mult x) y) when what you mean is mult (x-1) y. Function application binds very tightly in Haskell, so it's sometimes better to use too many parentheses rather too few, especially while you're still learning the basics of the language.
The error occurs because the type of (mult x) is Int -> Int but the type of y is Int, and you can't subtract those two things.

How is Ratio implemented in Haskell?

This is something I have been confused about for a while and I am not sure how I can learn more about it. Let's say I have the following program:
main :: IO ()
main = do
x <- liftM read getLine
y <- liftM read getLine
print (x % y)
If I run this with the input 6 and 2, it will print 3 % 1.
At what point does the simplification happen (namely the division by the gcd)? Is it implemented in show? If so, then is the underlying representation of the rational still 6 % 2? If not, then does (%) do the simplification? I was under the impression that (%) is a data constructor, so how would a data constructor do anything more than "construct"? More importantly, how would I actually go about doing similar things with my own data constructors?
I appreciate any help on the topic.
Ratio is actually implemented in GHC.Real (on GHC, obviously), and is defined as
data Ratio a = !a :% !a deriving (Eq)
The bangs are just there for strictness. As you can see, the function % is not a data constructor, but :% is. Since you aren't supposed to construct a Ratio directly, you use the % function, which calls reduce.
reduce :: (Integral a) => a -> a -> Ratio a
{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}
reduce _ 0 = ratioZeroDenominatorError
reduce x y = (x `quot` d) :% (y `quot` d)
where d = gcd x y
(%) :: (Integral a) => a -> a -> Ratio a
x % y = reduce (x * signum y) (abs y)
The rule is that if an operator starts with a colon :, then it is a constructor, otherwise it is just a normal operator. In fact, this is part of the Haskell standard, all type operators must have a colon as their first character.
You can just look at the source to see for yourself:
instance (Integral a) => Num (Ratio a) where
(x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
(x:%y) - (x':%y') = reduce (x*y' - x'*y) (y*y')
(x:%y) * (x':%y') = reduce (x * x') (y * y')
negate (x:%y) = (-x) :% y
abs (x:%y) = abs x :% y
signum (x:%_) = signum x :% 1
fromInteger x = fromInteger x :% 1
reduce :: (Integral a) => a -> a -> Ratio a
reduce _ 0 = ratioZeroDenominatorError
reduce x y = (x `quot` d) :% (y `quot` d)
where d = gcd x y

function call out of scope in where clause

I have the function pyths:
-- takes an Int and returns a list of pythagorean triples whose components
---- are at most the given Int
pyths :: Int a => a -> [(Int, Int, Int)]
pyths n = [(x, y, z) | x <- f, y <- f, z <- f, x^2 + y^2 == z^2]
where f = factors n
I get the error that factors is out of scope. How can I write this function so it's in scope?
I've tried:
pyths n = [(x, y, z) | x <- f, y <- f, z <- f, x^2 + y^2 == z^2 where f = factors n]
and:
pyths n = [(x, y, z) | x <- f, y <- f, z <- f, x^2 + y^2 == z^2, where f = factors n]
But then I just get syntax errors.
Note:
I know this may not actually do what I intend it to do.
As sepp2k said, you need to define factors. In your examples you change where f is defined, which uses factors in its definition, but no where do you say:
factors x = ...
Since there is no factors function defined in the Haskell prelude or other base libraries, you must write this yourself. The primes package will be useful to you, I expect.

Use QuickCheck by generating primes

Background
For fun, I'm trying to write a property for quick-check that can test the basic idea behind cryptography with RSA.
Choose two distinct primes, p and q.
Let N = p*q
e is some number relatively prime to (p-1)(q-1) (in practice, e is usually 3 for fast encoding)
d is the modular inverse of e modulo (p-1)(q-1)
For all x such that 1 < x < N, it is always true that (x^e)^d = x modulo N
In other words, x is the "message", raising it to the eth power mod N is the act of "encoding" the message, and raising the encoded message to the dth power mod N is the act of "decoding" it.
(The property is also trivially true for x = 1, a case which is its own encryption)
Code
Here are the methods I have coded up so far:
import Test.QuickCheck
-- modular exponentiation
modExp :: Integral a => a -> a -> a -> a
modExp y z n = modExp' (y `mod` n) z `mod` n
where modExp' y z | z == 0 = 1
| even z = modExp (y*y) (z `div` 2) n
| odd z = (modExp (y*y) (z `div` 2) n) * y
-- relatively prime
rPrime :: Integral a => a -> a -> Bool
rPrime a b = gcd a b == 1
-- multiplicative inverse (modular)
mInverse :: Integral a => a -> a -> a
mInverse 1 _ = 1
mInverse x y = (n * y + 1) `div` x
where n = x - mInverse (y `mod` x) x
-- just a quick way to test for primality
n `divides` x = x `mod` n == 0
primes = 2:filter isPrime [3..]
isPrime x = null . filter (`divides` x) $ takeWhile (\y -> y*y <= x) primes
-- the property
prop_rsa (p,q,x) = isPrime p &&
isPrime q &&
p /= q &&
x > 1 &&
x < n &&
rPrime e t ==>
x == (x `powModN` e) `powModN` d
where e = 3
n = p*q
t = (p-1)*(q-1)
d = mInverse e t
a `powModN` b = modExp a b n
(Thanks, google and random blog, for the implementation of modular multiplicative inverse)
Question
The problem should be obvious: there are way too many conditions on the property to make it at all usable. Trying to invoke quickCheck prop_rsa in ghci made my terminal hang.
So I've poked around the QuickCheck manual a bit, and it says:
Properties may take the form
forAll <generator> $ \<pattern> -> <property>
How do I make a <generator> for prime numbers? Or with the other constraints, so that quickCheck doesn't have to sift through a bunch of failed conditions?
Any other general advice (especially regarding QuickCheck) is welcome.
Here's one way to make a QuickCheck-compatible prime-number generator (stealing a Sieve of Eratosthenes implementation from http://en.literateprograms.org/Sieve_of_Eratosthenes_(Haskell)):
import Test.QuickCheck
newtype Prime = Prime Int deriving Show
primes = sieve [2..]
where
sieve (p:xs) = Prime p : sieve [x | x <- xs, x `mod` p > 0]
instance Arbitrary Prime where
arbitrary = do i <- arbitrary
return $ primes!!(abs i)
It can be used in QuickCheck like so:
prop_primes_dont_divide (Prime x) (Prime y) = x == y || x `mod` y > 0
For your use, you'd replace p and q with (Prime p) and (Prime q) in your property.
OK so here's what I did.
Top of file
{-# LANGUAGE NoMonomorphismRestriction #-}
import Test.QuickCheck
import Control.Applicative
All code as given in the question, except for prop_rsa. That was (obviously) heavily modified:
prop_rsa = forAll primePair $ \(p,q) ->
let n = p*q
in forAll (genUnder n) $ \x ->
let e = 3
t = (p-1)*(q-1)
d = mInverse e t
a `powModN` b = modExp a b n
in p /= q &&
rPrime e t ==>
x == (x `powModN` e) `powModN` d
The type for primePair is Gen (Int, Int), and the type for genUnder is Int -> Gen Int. I'm not exactly sure what the magic is behind forAll but I'm pretty sure this is correct. I've done some ad-hoc adjustments to 1) make sure it fails if I mess up the conditions and 2) make sure the nested forAll is varying the value of x across test cases.
So here's how to write those generators. Once I realized that <generator> in the documentation just meant something of type Gen a, it was cake.
genNonzero = (\x -> if x == 0 then 1 else x) `fmap` arbitrary
genUnder :: Int -> Gen Int
genUnder n = ((`mod` n) . abs) `fmap` genNonzero
genSmallPrime = ((\x -> (primes !! (x `mod` 2500))) . abs) `fmap` arbitrary
primePair :: Gen (Int, Int)
primePair = (,) <$> genSmallPrime <*> genSmallPrime
primePair took some trial and error for me to get right; I knew that some combinators like that should work, but I'm still not as familiar with fmap, <$> and <*> as I'd like to be. I restricted the computation to only select from among the first 2500 primes; otherwise it apparently wanted to pick some really big ones that took forever to generate.
Random thing to note
Thanks to laziness, d = mInverse e t isn't computed unless the conditions are met. Which is good, because it's undefined when the condition rPrime e t is false. In English, an integer a only has a multiplicative inverse (mod b) when a and b are relatively prime.

Resources