(Haskell) How to convert from Ratio Integer to Ratio Rational? - haskell

How does addition of two different ratios work? For instance, ratio integer and ratio rationals don't seem to get added. I tried evaluating the continued fraction for a given list.
Here's the code :
import Data.Ratio
f :: [Integer] -> Rational
f(x:xs)
| (null xs == True) = x
| otherwise = x + (1 % f xs)
What is the correct version of the code supposed to be? Since f yields a Ratio Rational, I feel that x, if type-casted to a Ratio rational number, will suffice.

No type conversion needed, use proper division between rationals.
import Data.Ratio
f :: [Integer] -> Rational
f [] = error "empty list"
f [x] = x % 1
f (x:xs#(_:_)) = x % 1 + 1 / f xs
Here, x % 1 makes x into a Rational (ok, that's conversion, if you want). We could also have used fromInteger, I think.
Then, between Rational values, we do not use % which produces a weird Ratio Rational, but we exploit / which produces a Rational instead.

Converting x to a Rational will not be sufficient here. Since you here write 1 % f xs. The type of (%) is (%) :: Integral a => a -> a -> Ratio a, and since f xs is a Rational, and Rational is not an instance of Integral, we thus need to fix a second issue.
It is however not that hard. We can for example make a function that calculates the inverse:
inverseR :: Integral a => Ratio a -> Ratio a
inverseR r = denominator r % numerator r
Since Ratio a is an instance of Num given a is an instance of Integral, we can use fromInteger :: Num a => Integer -> a:
f :: [Integer] -> Rational
f [x] = fromInteger x
f (x:xs) = fromInteger x + inverseR (f xs)
For example:
Prelude Data.Ratio> f [1,4,2,5]
60 % 49
Since 1 + 1/(4 + 1/(2 + 1/5)) = 1 + 1/(4 + 1/(11/5)) = 1 + 1/(4 + 5/11) = 1 + 1/(49/11) = 1 + 11/49 = 60 / 49.
We can further improve this by:
using fromIntegral :: (Integral a, Num b) => a -> b to convert any integral to a Ratio; and
by using (/) :: Fractional a => a -> a -> a.
We thus can generalize this to a function:
f :: (Integral a, Fractional b) => [a] -> b
f [x] = fromIntegral x
f (x:xs) = fromIntegral x + 1 / f xs
Which yields the same value:
Prelude Data.Ratio> f [1,4,2,5] :: Rational
60 % 49
We can use a foldr pattern, and avoid the explicit recursion:
f :: (Integral a, Fractional b) => [a] -> b
f = foldr1 (\x -> (x +) . (1 /)) . map fromIntegral

Related

Lagrange Interpolation for a schema based on Shamir's Secret Sharing

I'm trying to debug an issue with an implementation of a threshold encryption scheme. I've posted this question on crypto to get some help with the actual scheme but was hoping to get a sanity check on the simplified code I am using.
Essentially the the crypto system uses Shamir's Secret Sharing to combine the shares of a key. The polynomial is each member of the list 'a' multiplied by a increasing power of the parameter of the polynomial. I've left out the mod by prime to simplify the code as the actual implementation uses PBC via a Haskell wrapper.
I have for the polynomial
poly :: [Integer] -> Integer -> Integer
poly as xi = (f 1 as)
where
f _ [] = 0
f 0 _ = 0
f s (a:as) = (a * s) + f (s * xi) as
The Lagrange interpolation is:
interp0 :: [(Integer, Integer)] -> Integer
interp0 xys = round (sum $ zipWith (*) ys $ fmap (f xs) xs)
where
xs = map (fromIntegral .fst) xys
ys = map (fromIntegral .snd) xys
f :: (Eq a, Fractional a) => [a] -> a -> a
f xs xj = product $ map (p xj) xs
p :: (Eq a, Fractional a) => a -> a -> a
p xj xm = if xj == xm then 1 else negate (xm / (xj - xm))
and the split and combination code is
execPoly as#(a0:_) = do
let xs = zipWith (,) [0..] (fmap (poly as) [0..100])
let t = length as + 1
let offset = 1
let shares = take t (drop offset xs)
let sm2 = interp0 shares
putText ("poly and interp over " <> show as <> " = " <> show sm2 <> ". Should be " <> show a0)
main :: IO ()
main = do
execPoly [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] --1
execPoly [10,20,30,40,50,60,70,80] -- 2
execPoly(1) fails to combine to 10 but execPoly(2) combines correctly. The magic threshold seems to be 8.
Is my code correct? I am missing something in the implementation that limits the threshold size to 8?
As MathematicalOrchid said it was a precision problem.
Updated the code to:
f :: (Eq a, Integral a) => [a] -> a -> Ratio a
f xs xj = product $ map (p xj) xs
p :: (Eq a, Integral a)=> a -> a -> Ratio a
p xj xm = if xj == xm then (1 % 1) else (negate xm) % (xj - xm)
And it works as expected.

Can't properly understand lambdas in Haskell

I have following code, implmenting inverse function calculation, basing on this formulas:
derivation :: (Fractional a) => (a -> a) -> (a -> a)
derivation f = \ x -> ( ( f (x + dx) - f (x) ) / dx ) where dx = 0.1
evalA k f
| k == 0 = \x -> x
| otherwise = \x -> (derivation (evalA (k-1) f) x) / (derivation f x)
inverseFun f x =
let
x0 = 3.0
eps = 0.001
iter k prev sum =
let
elemA = evalA k f x0
elemB = prev * (x - (f x0)) / (if k == 0 then 1 else k)
newItem = elemA * elemB
in
if abs (newItem) < eps
then sum
else iter (k + 1) elemB (sum + newItem)
in
iter 0 1.0 0.0
f1 = \x -> 1.0 * x * x
main = do
print $ inverseFun f1 2.5
I need to optimise it by moving evalA inside the inverseFun and store previous step calculation A'n/F' to reuse it on the next iteration, if possible. As far as I understand, each time evalA returns some sort of function and x applies afterwards, right before declaring elemA.
How can I convert my evalA or rewrite it to store previous results (by passing these results in iter, obviously)?
Don't mind if this calculations are not too precise, it requires good x0 and eps choice. My main question is in lambda conversion.
If you change your definition of inverseFun such that the (if k == 0 then 1 else k) is instead fromIntegral (if k == 0 then 1 :: Int else k), then you can provide type signatures to all of your functions:
derivation :: (Fractional a) => (a -> a) -> a -> a
evalA :: (Fractional a) => Int -> (a -> a) -> a -> a
inverseFun :: (Fractional a, Ord a) => (a -> a) -> a -> a
f1 :: (Fractional a) => a -> a
Which certainly helps out.
This is actually important for my solution to your problem, since we need k to be an Int, and you've used it as a Fractional a => a. The fromIntegral fixes that, but it needs to know that it's an Int, so I just added the inline type signature to help the compiler along.
Since your function only depends on the previous single value, you can use our handy friend from Prelude, iterate :: (a -> a) -> a -> [a]. This applies a function over and over again, producing an infinite list of values. We can then index it at any point to get the desired result (this is why having k an Int is important!).
Our function will look like
evalA :: Fractional a => Int -> (a -> a) -> a -> a
evalA k f = iterate go id !! k
where
go = ???
Here id is the same as your base case of \x -> x, just shorter and with more optimization rules. It serves as the initial value for generating this list. To implement go, the actual computation, we need it to accept the previous result as its argument:
where
go prev = \x -> derivation prev x / derivation f x
But this is considered "poor style" by hlint, and so it is suggested to convert this to the form
where
go prev x = derivation prev x / derivation f x
And that's it! I tested it and got the exact same result for your example input. The full code can be viewed here.

Type declaration for number division

I tried all possible type declarations but I can't make this code even compile. The trick is in handling types for division. I tried Num a, Fractional a, Float a etc.
cube x = x * x * x
sum' term a next b =
if a > b
then 0
else term a + sum' term (next a) next b
integral f a b n = (h / 3) * (sum' term 0 succ n) where
h = (b - a) / n
y k = f $ a + (k * h)
term k
| k == 0 || k == n = y k
| odd k = 4 * y k
| even k = 2 * y k
main = do
print $ integral cube 0 1 100 -- 0.25
print $ (\x -> 3 * x * x) 1 3 100 -- 26
I isolated problem by deleting (/) function. This code compiles without any type declaration at all:
cube x = x * x * x
sum' term a next b =
if a > b
then 0
else term a + sum' term (next a) next b
integral f a b n = (sum' term 0 succ n) where
h = (b - a)
y k = f $ a + (k * h)
term k
| k == 0 || k == n = y k
| odd k = 4 * y k
| even k = 2 * y k
main = do
print $ integral cube 0 1 100
Another question is how to debug cases like this? Haskell's error messages doesn't help much, it's kind of hard to understand something like The type variable a0 is ambiguous or Could not deduce (a1 ~ a).
P. S. It's ex. 1.29 from SICP.
Update
Final answer is:
cube :: Num a => a -> a
cube x = x * x * x
sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double
sum' term a next b =
if a > b
then 0
else term a + sum' term (next a) next b
integral :: (Double -> Double) -> Double -> Double -> Int -> Double
integral f a b n = (h / 3) * sum' term 0 (+1) n where
h = (b - a) / n' where n' = fromIntegral n
y k = f $ a + (k * h)
term k
| k == 0 || k == n = y k'
| odd k = 4 * y k'
| even k = 2 * y k'
where k' = fromIntegral k
main = do
print $ integral cube 0 1 100 -- 0.25
print $ integral cube 0 1 1000 -- 0.25
print $ integral (\x -> 3 * x * x) 1 3 100 -- 26
/ is only used for types that are instances of Fractional, for Integral types use quot. You can use quot as an infix operator using backticks:
h = (b - a) `quot` n
The types of the two are
(/) :: Fractional a => a -> a -> a
quot :: Integral a => a -> a -> a
There are no types that are instances of both Fractional and Integral, which is why none of the type signatures would work. Unfortunately GHC doesn't know that it's impossible for a type to be an instance of both classes, so the error messages are not very intuitive. You get used to the style of GHC error messages though, and the detail they give helps a lot.
Also, as was suggested in the comments, I completely agree that all top level definitions should be given type signatures (including main). It makes error messages a lot easier to read.
Edit: Based on the comments below, it looks like what you want is something more like this (type signature-wise)
cube :: Num a => a -> a
sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double
integral :: (Double -> Double) -> Double -> Double -> Int -> Double
You will need to use fromIntegral to convert from Int to Double in h and in k. The type errors should be at least a bit more readable with these type signatures though.

Implementing Collatz Function

Learn You a Haskell mentions the Collatz Sequences:
We take a natural number. If that number is even, we divide it by two.
If it's odd, we multiply it by 3 and then add 1 to that.
When I tried to implement it, I ran into a problem
collatz :: (Integral a) => a -> [a]
collatz x
| odd x = f x : collatz (f x)
| otherwise = g x : collatz (g x)
where f y = y*3 + 1
g y = y/2
But I get this compile-time error:
CollatzSeq.hs:10:16:
Could not deduce (Fractional a) arising from a use of `g'
from the context (Integral a)
bound by the type signature for collatz :: Integral a => a -> [a]
at CollatzSeq.hs:7:12-35
Possible fix:
add (Fractional a) to the context of
the type signature for collatz :: Integral a => a -> [a]
In the first argument of `(:)', namely `g x'
In the expression: g x : collatz (g x)
In an equation for `collatz':
collatz x
| odd' x = f x : collatz (f x)
| otherwise = g x : collatz (g x)
where
f y = y * 3 + 1
g y = y / 2
As I understand, the problem is that calling collatz (g x) can return a Fractional since y / 2 returns a Double:
Prelude> let x = 4 / 2
Prelude> :t x
x :: Double
I tried to fix this type error by adding floor in front of the y/2, but that didn't work.
Please tell me how to fix this error.
Use div instead of (/). Alternately, if you want another rounding strategy than floor, you may use fromIntegral, as in
round (fromIntegral y / 2)
The error comes from the way / is defined. GHCI shows this result for :t (/):
(/) :: Fractional a => a -> a -> a
An alternative would be to use div, which has the type signature:
div :: Integral a => a -> a -> a
Secondly, you are skipping the input term in your current implementation. That should not be the case.
Finally, you need to add the base case for input = 1, otherwise your function will get caught in an infinite loop. You may change it to:
collatz :: (Integral a) => a -> [a]
collatz 1 = [1]
collatz x
| odd x = x : collatz (f x)
| otherwise = x : collatz (g x)
where f y = y*3 + 1
g y = y `div` 2

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

Resources