recursive function: No instance (Num) arising from the literal - haskell

I'm trying to make a recursive function which defines division in terms of subtraction. So I have created a new type "DividedResult" to take into account a "divide by zero" case. Do my datatype declaration and function type declaration make sense? I get such errors:
No instance for (Num DividedResult) arising from the literal `0' In the third argument of `go'
Could not deduce (Num DividedResult) arising from a use of `+'
(Probably have to create a Num instance? I have tried, but it doesn't work for me).
Here is my code:
data DividedResult = Result Integer | DividedByZero
dividedBy :: Integer -> Integer -> (DividedResult, Integer)
dividedBy num denom = go num denom 0
where go n d count
| d == 0 = (DividedByZero, n)
| abs n < abs d = (count, n)
| abs n >= abs d && n > 0 && d > 0 = go (n - d) d (count + 1)
| abs n >= abs d && n > 0 && d < 0 = go (n + d) d (count - 1)
| abs n >= abs d && n < 0 && d < 0 = go (n - d) d (count + 1)
| abs n >= abs d && n < 0 && d > 0 = go (n + d) d (count - 1)

The reason you get that error, is because you are trying to return an actual Integer here:
| abs n < abs d = (count, n)
By returning count, an Integer instead of a DividedResult, the compiler thinks you are trying to cast a number into a DividedResult, which is only possible if DividedResult is a Num
In this case, making DividedResult an instance of Num would be overkill; you just need to wrap count:
| abs n < abs d = (Result count, n)

Related

How do I get the sums of digits of the negative large number in Haskell?

sumOfDigitsPosNeg x =
if x == 0 then 0
else if x < 0 then sumOfDigitsPosNeg ((-1)*x `div` 10) + mod ((-1)*x) 10
else sumOfDigitsPosNeg (x `div` 10) + mod x 10
I've tried with these code, but if the input is more than one digit, the output is wrong. I'm just confused how to convert the negative numbers into positive. How do I approach this problem?
Using abs this is quite easy. We just operate on the absolute value of the number input.
sumDigits :: Integral t => t -> t
sumDigits 0 = 0
sumDigits n = a `mod` 10 + sumDigits (a `div` 10)
where a = abs n
You can work with a helper go function that will only retrieve the absolute value. We thus call go with the abs :: Num a => a -> a of the item:
sumOfDigitsPosNeg :: Integral a => a -> a
sumOfDigitsPosNeg = go . abs
where go 0 = 0
go n = r + go q
where (q, r) = quotRem n 10

Why is the following Haskell code hanging?

I'm new to Haskell. I was trying to solve the diophantine equation |x^y-y^x| is prime, using Haskell, for a given upper bound x, y < n.
So, I wrote this Haskell code:
-- list of primes
listprimesupto :: Integral a => a -> [a]
listprimesupto 1 = []
listprimesupto 2 = [2]
listprimesupto n = let halflstprimes = (listprimesupto (n `div` 2))
in halflstprimes++[i|i<-[((n `div` 2)+1)..n], (length [x|x<-halflstprimes, (i `mod` x) == 0])==0 ]
-- is prime?
is_prime :: Integral a => a -> Bool
is_prime 1 = False
is_prime n = let halflstprimes = (listprimesupto (n `div` 2))
in (length [x|x<-halflstprimes, (n `mod` x) == 0])==0
-- solve |x^y - y^x| == prime
xy_yx_p :: Integral t => t -> [(t, t)]
--xy_yx_p n = [(x,y)|x<-[2..n], y<-[2..n], x < y, (abs (x^y-y^x)) `elem` (listprimesupto (n^3))] -- version 1, works but upper limit too small
xy_yx_p n = [(x,y)|x<-[2..n], y<-[2..n], x < y, (let t=abs (x^y-y^x) in is_prime t)==True] -- version 2, hangs for n>3 ...
xy_yx_p n (version 2, uncommented) hangs for n > 3, in GHCi. Ctrl-C doesn't even work. I have to kill ghc from Activity Monitor (I'm on Mac).
Any idea what am I doing wrong in xy_yx_p? The other two functions seem to work fine.
Thanks in advance.
So, if it hangs for n = 4, what's so special about that case? Well, it's t. For x = 2 and y = 4, you will get
t = abs (2 ^ 4 - 4 ^ 2)
= abs (16 - 16 )
= abs 0
= 0
Therefore, you use 0 in is_prime, and thereby also in listprimesupto. This leads to a never ending recursion:
listprimesupto 0 = let halflstprimes = (listprimesupto (0 `div` 2))
in -- .....
So make sure that you handle non-positive inputs:
listprimesupto n | n <= 0 = []
is_prime n | n <= 1 = False

How can I calculate Σ_{i=m}^n (m+i)^n?

I'm currently trying to calculate the following sum:
sum2015 :: Integer->Integer->Integer
sum2015 m n
| m>n = 0
| otherwise = (m+m)^n + sum2015 (m+1) n
As an example, sum2015 0 1 should return 1. However, it returns 2. What did I do wrong?
You're not calculating that sum. Note that m in (m + i)^n must stay fixed, but you use a new m here:
| otherwise = … + sum2015 (m+1) n
-- ^^^^^
-- oh oh
Therefore you get:
sum2015 0 1
= (0 + 0)^1 + sum2015 (0 + 1) 1
= (0 + 0)^1 + (1 + 1)^1 + sum2015 (1 + 1) 1
= (0 + 0)^1 + (1 + 1)^1 + 0
= 0 + 2
= 2
Instead, calculate all (m + i)^n and sum them afterwards:
sum2015 :: Integer -> Integer -> Integer
sum2015 m n = sum . map (\i -> (m + i) ^ n) $ [m..n]
Or, if you're not allowed to use that, use a worker:
sum2015 :: Integer -> Integer -> Integer
sum2015 m n = go m
where go i = ...
I can offer this option:
sum2015 m n = sum [(m + i) ** n | i <- [m..n]]
Firstly, I created list of numbers from m to n "[m..n]".
After for each i in this list, I computing terms of the sum.
Finally, just use "sum" function for obtained result list.
'**' - Pow function

Stack overflow in my recursive function

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)

Haskell Int64 inconsistent?

I am trying to solve the problem 2's complement here (sorry, it requires login, but anyone can login with FB/google account). The problem in short is to count the number of ones appearing in the 2's complement representation of all numbers in a given range [A, B] where A and B are within the 32-bit limits (231 in absolute value). I know my algorithm is correct (it's logarithmic in the bigger absolute value, since I already solved the problem in another language).
I am testing the code below on my machine and it's giving perfectly correct results. When it runs on the Amazon server, it gives a few wrong answers (obviously overflows) and also some stack overflows. This is not a bug in the logic here, because I test the same code on my machine on the same test inputs and get different results. For example, for the range [-1548535525, 662630637] I get 35782216444 on my machine, while according to the tests, my result is some negative overflow value.
The only problem I can think of, is that perhaps I am not using Int64 correctly, or I have a wrong assumption about it's operation.
Any help is appreciated. Code is here.
The stack overflows are a bug in the logic.
countOnes !a !b | a == b = countOnes' a
countOnes' :: Int64 -> Integer
countOnes' !0 = 0
countOnes' !a = (fromIntegral (a .&. 1)) + (countOnes' (a `shiftR` 1))
Whenever you call countOnes' with a negative argument, you get a nonterminating computation, since the shiftR is an arithmetic shift and not a logical one, so you always shift in a 1-bit and never reach 0.
But even with a logical shift, for negative arguments, you'd get a result 32 too large, since the top 32 bits are all 1.
Solution: mask out the uninteresting bits before calling countOnes',
countOnes !a !b | a == b = countOnes' (a .&. 0xFFFFFFFF)
There are some superfluous guards in countOnes,
countOnes :: Int64 -> Int64 -> Integer
countOnes !a !b | a > b = 0
-- From here on we know a <= b
countOnes !a !b | a == b = countOnes' (a .&. 0xFFFFFFFF)
-- From here on, we know a < b
countOnes !0 !n = range + leading + (countOnes 0 (n - (1 `shiftL` m)))
where
range = fromIntegral $ m * (1 `shiftL` (m - 1))
leading = fromIntegral $ (n - (1 `shiftL` m) + 1)
m = (getLog n) - 1
-- From here on, we know a /= 0
countOnes !a !b | a > 0 = (countOnes 0 b) - (countOnes 0 (a - 1))
-- From here on, we know a < 0,
-- the guard in the next and the last equation are superfluous
countOnes !a !0 | a < 0 = countOnes (maxInt + a + 1) maxInt
countOnes !a !b | b < 0 = (countOnes a 0) - (countOnes (b + 1) 0)
countOnes !a !b | a < 0 = (countOnes a 0) + (countOnes 0 b)
The integer overflows on the server are caused by
getLog :: Int64 -> Int
--
countOnes !0 !n = range + leading + (countOnes 0 (n - (1 `shiftL` m)))
where
range = fromIntegral $ m * (1 `shiftL` (m - 1))
leading = fromIntegral $ (n - (1 `shiftL` m) + 1)
m = (getLog n) - 1
because the server has a 32-bit GHC, while you have a 64-bit one. The shift distance/bit width m is an Int (and because it's used as the shift distance, it has to be).
Therefore
m * (1 `shiftL` (m-1))
is an Int too. For m >= 28, that overflows a 32-bit Int.
Solution: remove a $
range = fromIntegral m * (1 `shiftL` (m - 1))
Then the 1 that is shifted is an Integer, hence no overflow.

Resources