I'm new to Haskell and i don't understand why my guard won't accept it. here's my code. The guard should fire in case b is a divider of a.
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = f p n
| otherwise = f n p
where
f :: Integer -> Integer -> Integer;
f a b
| (fromInteger (a `div` b) / 1 == a / b) = b
| otherwise = f a (b - 1)
Here's the error shown.
testscript.hs:168:28: error:
• No instance for (Fractional Integer) arising from a use of ‘/’
• In the first argument of ‘(==)’, namely
‘fromInteger (a `div` b) / 1’
In the expression: (fromInteger (a `div` b) / 1 == a / b)
In a stmt of a pattern guard for
an equation for ‘f’:
(fromInteger (a `div` b) / 1 == a / b)
|
168 | | (fromInteger (a `div` b) / 1 == a / b) = b | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
I think you make it the function more complex that necessary. Converting numbers between the Integer and Floating world can be dangerous, since it introduces rounding problems.
If I understand it correctly, you want to check if a is dividable by b. You can check this by verifying that mod a b == 0, and we are still in the integer worlds. So we can rewrite the program to:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| p > n = f p n
| otherwise = f n p
where f a b | mod a b == 0 = b
| otherwise = f a (b-1)
Since a does not change in the recursive calls, we can factor that out:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
We can also generalize the signature to let it work with any Integral type:
gCF :: Integral i => i -> i -> i
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
i found a solution!
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = floor (f (fromInteger p) (fromInteger n) (fromInteger n))
| otherwise = floor (f (fromInteger n) (fromInteger p) (fromInteger p))
where
f :: Float -> Float -> Float -> Float;
f a b c
| (fromInteger (floor (a / c)) == a / c) && (fromInteger (floor (b / c)) == b / c) = c
| otherwise = f a b (c - 1)
Related
I am using Euclid's algorithm for computing GCD(M,N), the greatest common divisor of two integers M and N.
Though this code works well, I felt it's bit cumbersome to wrap it with max, min, and abs for both variables (a, b).
Can anyone suggest a better way to make the code less verbose?
I found the built-in gcd type was defined as gcd :: Integer a => a -> a -> a, but I cannot simply use it. What do I need to change in order to reuse the type definition?
gcd2 :: Int -> Int -> Int
gcd2 a b =
let x = max (abs a) (abs b)
y = min (abs a) (abs b)
in if (y == 0) || (x == y && x > 0)
then x
else gcd2 y (x-y)
Well, inspired by chi, I changed the code as below.
gcd3 :: Int -> Int -> Int
gcd3 a b | a < 0 = gcd3 (-a) b
| b < 0 = gcd3 a (-b)
| b > a = gcd3 b a
| b == a || b == 0 = a
| otherwise = gcd3 b (a-b)
This is the best I can do. :)
As suggested by chi in his answer, to avoid using abs in each recursive step I’d define a GCD local function where you pass the absolute value of the arguments. This way the implementation is pretty straightforward:
gcd :: Int -> Int -> Int
gcd a b = gcd' (abs a) (abs b)
where gcd' a 0 = a
gcd' a b = gcd' b (a `mod` b)
You can look at how it is implemented in base:
gcd :: (Integral a) => a -> a -> a
gcd x y = gcd' (abs x) (abs y)
where gcd' a 0 = a
gcd' a b = gcd' b (a `rem` b)
I am making calculating 2^(n-1) mod n. I had a problem with Haskell.
parse error (possibly incorrect indentation or mismatched brackets)
|
5 | | (mod e 2 == 0) = md (mod b*b m) (div e 2) m r
| ^
But the problem is I don't know what is the problem
modf :: Int -> Int
modf n = md 2 (n-1) n r
where
md b e m r
| (mod e 2 == 0) = md (mod b*b m) (div e 2) m r
| otherwise = md (mod b*b m) (div e 2) m (mod r*b m)
The main problem is that the indentation level of the guards is the same as the md function itself). You need to indent it by at least one space:
modf :: Int -> Int
modf n = md 2 (n-1) n r
where
md b e m r
| (mod e 2 == 0) = md (mod b*b m) (div e 2) m r
| otherwise = md (mod b*b m) (div e 2) m (mod r*b m)
Now the syntax error has been resolved, but it will raise an error on the fact that you use r, but never defined r.
We can implement this more elegantly by:
import Data.Bits(shiftR)
modf :: Int -> Int
modf m = go 2 (m-1)
where go k 1 = k
go k n | even n = go2
| otherwise = mod (go2 * k) m
where go2 = go (mod (k*k) m) (shiftR n 1)
I have written the following predicate (Lines 94-99)
diffFreqMatrix :: Fractional a => [[Rating a]] -> [a]
diffFreqMatrix (x:xs) = diffFreqMatrixH (x:xs) (matrixPairs (length x))
diffFreqMatrixH _ [] = []
diffFreqMatrixH x ((a,b):ys) = [(diffFreqMatrixH2 x a b 0 0)] ++ diffFreqMatrixH x ys
diffFreqMatrixH2 [] _ _ x y = x / y
diffFreqMatrixH2 (x:xs) a b summ num = if (((x!!a) /= NoRating) && ((x!!b) /= NoRating)) then diffFreqMatrixH2 xs a b (summ + ((x!!a) - (x!!b))) (num + 1) else diffFreqMatrixH2 xs a b summ num
supposedly it calculates an average I want but i'm getting this error
ERROR file:.\project.hs:98 - Cannot infer instance
*** Instance : Fractional (Rating a)
*** Expression : diffFreqMatrixH2
Helpers im using in case u want to take a look
matrixPairs :: Num a => a -> [(a,a)]
matrixPairs 0 = []
matrixPairs c = matrixPairsH 0 0 (c-1)
matrixPairsH a b c = [(a,b)] ++ if ((b == c) && (a == c)) then [] else if (b == c) then (if (a==c) then [] else matrixPairsH (a+1) 0 c ) else matrixPairsH a (b+1) c
differeneRatings :: Fractional a => Rating a -> Rating a -> a
differeneRatings NoRating (R a) = 0
differeneRatings (R a) NoRating = 0
differeneRatings NoRating NoRating = 0
differeneRatings (R a) (R b) = a - b
You use Rating as as if they were just numbers here:
(x!!a) - (x!!b)
You presumably need to use case or similar to pattern match on x!!a and x!!b to extract the number they contain. You can move the check for NoRating into that case match to simplify your code. For example:
case (x!!a, x!!b) of
(YesRating ra, YesRating rb) -> diffFreqMatrixH2 xs a b (summ + ra - rb) (num + 1)
_ -> diffFreqMatrixH2 xs a b summ num
Once you get this working the way you want, I encourage you to post to the code review StackExchange; your code can be cleaned up significantly to be both simpler and faster.
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.
I'm new to Haskell and struggling with some subtleties of syntax. Why is this fine:
reduceBy a f n
| n < 2 = (a,f)
| (a `mod` n) == 0 =
reduceBy( floor $ fromIntegral a / fromIntegral n) (f++[n]) n
| otherwise = (a, f)
While this has errors: (Couldn't match expected type `(a, [a])' against inferred type `[a] -> a -> (a, [a])' )
reduceBy a f n
| n < 2 = (a,f)
| (a `mod` n) == 0 =
reduceBy( floor(fromIntegral a / fromIntegral n) (f++[n]) n )
| otherwise = (a, f)
?
Your new closing parenthesis comes too late. It should be
... reduceBy (floor(fromIntegral a / fromIntegral n)) ...
The $ binds fairly weakly, but parentheses trump everything.