I have some problems with the different types in Haskell, how can I solve this?
Couldn't match expected type Integer with actual type Int -> t0 -> t0
Thanks
isPrime :: Int -> Bool
isPrime number
| (number == 1) || (number == 2) = True
| even number = False
| otherwise = checkDiv number (fromInteger (`sqrt` number))
checkDiv :: Int -> Int -> Bool
checkDiv number divisor
| number == 2 = True
| (floor number `mod` divisor) == 0 = False
| otherwise = checkDiv number $ divisor - 1
I've figured out the modifications to get the code to compile, but it does not actually find primes. I had to change
fromInteger (`sqrt` number)
to
floor $ sqrt $ fromIntegral number
The backtick notation around a function name is to turn it in to an infix "operator" of sorts, so you could do
mod x y
or
x `mod` y
but not
`mod` x y
Next, you were using fromInteger instead of fromIntegral, which is the one that works on Ints (Int and Integer are different types). Finally, I removed the floor from number in the second guard of checkDiv, since number is already an Int.
isPrime :: Int -> Bool
isPrime number
| (number == 1) || (number == 2) = True
| even number = False
| otherwise = checkDiv number (floor $ sqrt $ fromIntegral number)
checkDiv :: Int -> Int -> Bool
checkDiv number divisor
| number == 2 = True
| (number `mod` divisor) == 0 = False
| otherwise = checkDiv number $ divisor - 1
So let's work through your code so that you can see what's going on. If I were to compute checkDiv 17 4 (4 is floor $ sqrt $ fromIntegral 17), it would perform
checkDiv 17 4
| 17 == 2 No
| 17 `mod` 4 == 0 No
| otherwise = checkDiv 17 (4 - 1) = checkDiv 17 3
checkDiv 17 3
| 17 == 2 No
| 17 `mod` 3 == 0 No
| otherwise = checkDiv 17 (3 - 1) = checkDiv 17 2
checkDiv 17 2
| 17 == 2 No
| 17 `mod` 2 == 0 No
| otherwise = checkDiv 17 (2 - 1) = checkDiv 17 1
checkDiv 17 1
| 17 == 2 No
| 17 `mod` 1 == 0 Yes = False
But 17 is prime! Do you see where your algorithm is doing something wrong?
Related
I'm trying to check for leap years, which are "years either divisible by 400 or divisible by 4 but not divisible by 100." Removing one of the conditions still doesn't return a true on actual leap years. Only the z value in the tuple counts toward the divisibility but these conditions never return a True value for an actual leap year.
checkLeap :: (Int, Int, Int) -> Bool
checkLeap (x,y,z)
| z == 400 `mod` 1 = True
| z == 4 `mod` 1 && z /= 100 `mod` 1 = True
| otherwise = False
mod is 0 when it's divisible, and it also doesn't go all the way on the end in Haskell. Try this instead:
checkLeap :: (Int, Int, Int) -> Bool
checkLeap (x,y,z)
| z `mod` 400 == 0 = True
| z `mod` 4 == 0 && z `mod` 100 /= 0 = True
| otherwise = False
I am trying to do a recursive function that should give the sum of all integers between and including its two arguments. For example,
sumFromTo 5 8 is 5 + 6 + 7 + 8 = 26. If the first argument is greater than the
second, the function should return 0.
This is what I got currently but I am a beginner and I don't think I did it right
sumFromTo :: Int -> Int -> Int
sumFromTo x y
| x == 1 = 1
| y == 1 = 1
| x > 1 && y > 1 = x + y sumFromTo (x - 1)
| otherwise = 0
Any help please?
You can use a list comprehension to do this very simply:
sumFromTo :: Int -> Int -> Int
sumFromTo x y = sum [x..y]
However, I'm not sure what you'd want to do if x == y.
In the code you've given, your recursive definition isn't correct syntax. You've only given sumFromTo one argument, when it needs two, and you appear to have missed a + between the y and the function.
λ> sumFromTo 8 5
0
λ> sumFromTo 5 8
26
λ> sumFromTo 8 8
8
λ>
[a..b] means a list with a step of 1 between a and b, so [1..4] is [1,2,3,4]
Thanks to Phylogenesis, here is a recursive definition:
sumFromTo :: Int -> Int -> Int
sumFromTo x y
| x > y = 0
| x == y = x
| otherwise = x + sumFromTo (x + 1) y
I think you make the problem too complex if you want to implement this with recursion. Basically there are two cases:
one where the lower bound is greater than the upper bound, in which case the sum is zero; and
one where the lower bound is less than or equal to the upper bound.
The first case (1) can be expressed by writing:
sumFromTo x y | x > y = 0
In the second case, the result is the lower bound plus the sum of the lowerbound plus one to the upper bound, so:
| otherwise = x + sumFromTo (x+1) y
and putting these together:
sumFromTo :: (Num a, Ord a) => a -> a -> a
sumFromTo x y | x > y = 0
| otherwise = x + sumFromTo (x+1) y
the following code:
Module Main where
main :: IO ()
main = do putStrLn "hello"
putStrLn $ "2 exp 6 = " ++ show (2 `exp1` 6)
exp1 :: Integer -> Integer -> Integer
exp1 x n | n == 0 = 1
| n == 1 = x
| even n = exp1 (x*x) m
| odd n = x * exp1 (x*x) (m-1)
where m = n `div` 2
produces the output 4 for 2 `exp1` 6, which is obviously wrong.
thanks
The odd case is wrong. You end up evaluating exp1 4 3 to be 4 * (exp1 16 0).
Code is here , when i call numberOf 3 or numberOf integer>2 im getting this error ERROR - C stack overflow . My code should change numbers between 2^(n-2) (2^n)-1 for n>2 to Binary and check if is there consecutive 0 or not . If is there dont count and if there isnt +1 .
numberOf :: Integer -> Integer
numberOf i = worker i
worker :: Integer -> Integer
worker i
| (abs i) == 0 = 0
| (abs i) == 1 = 2
| (abs i) == 2 = 3
| otherwise = calculat (2^((abs i)-2)) ((2^(abs i))-2)
calculat :: Integer -> Integer -> Integer
calculat ab bis
| ab == bis && (checker(toBin ab)) == True = 1
| ab < bis && (checker(toBin ab)) == True = 1 + (calculat (ab+1) bis)
| otherwise = 0 + (calculat (ab+1) bis)
checker :: [Integer] -> Bool
checker list
| list == [] = True
| 0 == head list && (0 == head(tail list)) = False
| otherwise = checker ( tail list)
toBin :: Integer -> [Integer]
toBin n
| n ==0 = [0]
| n ==1 = [1]
| n `mod` 2 == 0 = toBin (n `div` 2) ++ [0]
| otherwise = toBin (n `div` 2) ++ [1]
Tests :
numberOf 3 Answer:(5)
numberOf 5 (13)
numberOf 10 (144)
numberOf (-5) (13)
The problem lies with your definition of calculat. You have the cases of ab == bis and ab < bis, but the only place you call calculat is from worker with the arguments 2^(abs i - 1) and 2^(abs i - 2). Since the first number (ab) will always be larger than the second (bis), checking for ab < bis is pretty silly. In your otherwise condition you then increment ab, ensuring that this function will never terminate. Did you instead mean otherwise = calculat ab (bis + 1)?
You could also clean your code up substantially, there are many places where you've done things the hard way, or added unnecessary clutter:
-- Remove worker, having it separate from numberOf was pointless
numberOf :: Integer -> Integer
numberOf i
| i' == 0 = 0
| i' == 1 = 2
| i' == 2 = 3
-- Lots of unneeded parentheses
| otherwise = calculat (2 ^ (i' - 1)) (2 ^ i' - 2)
-- Avoid writing the same expression over and over again
-- define a local name for `abs i`
where i' = abs i
calculat :: Integer -> Integer -> Integer
calculat ab bis
-- Remove unneeded parens
-- Don't need to compare a boolean to True, just use it already
| ab == bis && checker (toBin ab) = 1
| ab < bis && checker (toBin ab) = 1 + calculat (ab + 1) bis
-- 0 + something == something, don't perform unnecessary operations
| otherwise = calculat (ab + 1) bis
-- Pattern matching in this function cleans it up a lot and prevents
-- errors from calling head on an empty list
checker :: [Integer] -> Bool
checker [] = True
checker (0:0:_) = False
checker (_:xs) = checker xs
-- Again, pattern matching can clean things up, and I find an in-line
-- if statement to be more expressive than a guard.
toBin :: Integer -> [Integer]
toBin 0 = [0]
toBin 1 = [1]
toBin n = toBin (n `div` 2) ++ (if even n then [0] else [1])
In calculat in case ab == bis but checker returns false you cant return from the function.
How about:
| ab >= bis && (checker(toBin ab)) == True = 1
| ab < bis && (checker(toBin ab)) == True = 1 + (calculat (ab+1) bis)
| otherwise = 0 + (calculat (ab+1) bis)
| ab >= bis = 0
| ab < bis == True = 0 + (calculat (ab+1) bis)
| otherwise = 0 + (calculat (ab+1) bis)
So what I would like to do is find out if the answer is an integer and return that answer. Here is an example. If I input 5, it would return 1.
The example checks if the integer is divisible by 5 or 6 and then returns it if it is.
division :: Int -> Int
division 5
| 5 / 5 == Int || 5 / 6 == Int = Int
| otherwise = 2
Use mod
f x | x `mod` 5 == 0 = x `div` 5
f x | x `mod` 6 == 0 = x `div` 6
f _ = 2
This will return x/5 if it is an int, if not, it will return x/6 if it is an int, else it will just return 2.