Haskell program crashing - infinite recursion? wrong where statement? - haskell

I need to calculate the product of all factorials from 1..n.
When I call this function double_factorial (with at least 2 or 3 as args),
it seems to be called for a moment, but nothing happens, and after a few seconds the GHCi just closes. What is wrong? Is there some infinite recursion that I can't see?
Here is my code :
double_factorial :: Integer->Integer
double_factorial n
| n<0 = error "negative number is given"
| n==0 = 1
| otherwise = (factorial n)*(double_factorial n-1)
where
factorial :: Integer->Integer
factorial n
| n == 0 = 1
| otherwise = n*(factorial n-1)

(double_factorial n-1) means ((double_factorial n) - 1) so yes, it's an infinite recursion problem.

First off, because you opened GHCi directly, the terminal window in which it is running closes as soon as GHCi stops running. If you open up cmd (or similar terminal) and then use GHCi from there, you can see the error that GHCi throws as it stops running. In this case we get:
<interactive>: out of memory
This does suggest an infinite recursion problem, as you already suspected.
Because factorial is the simpler function, it's easier to check if its recursive call is the culprit. It is, as factorial n - 1 means (factorial n) - 1 and not factorial (n - 1). And calling factorial n in the definition of factorial n is pretty much the textbook case of infinite recursion. In double_factorial we see the same problem.

You have a recursion problem: f x - 1 is not the same as f (x - 1). Solution (removing unneeded parentheses and adding the needed ones):
double_factorial :: Integer->Integer
double_factorial n
| n<0 = error "negative number is given"
| n==0 = 1
| otherwise = factorial n * double_factorial (n-1)
where
factorial :: Integer->Integer
factorial n
| n == 0 = 1
| otherwise = n * factorial (n-1)

Related

Keep getting stack overflow

I am repeatedly getting a stack overflow on my solution to Project Euler #7 and i have no idea why.
Here is my code:
import System.Environment
checkPrime :: Int -> Bool
checkPrime n = not $ testList n [2..n `div` 2]
--testList :: Int -> [Int] -> Bool
testList _ [] = False
testList n xs
| (n `rem` (head xs) == 0) = True
| otherwise = testList n (tail xs)
primesTill n = sum [1 | x <- [2..n], checkPrime x]
nthPrime n = nthPrime' n 2
nthPrime' n x
| (primesTill x == n) = x
| otherwise = nthPrime' n x+1
main = print (nthPrime 10001)
resolving the stackoverflow
As #bheklilr mentioned in his comment the stackoverflow is caused by a wrong evaluation order in the otherwise branch of the nthPrime' function:
nthPrime' n x+1
Will be interpreted as
(nthPrime' n x)+1
Because this expression is called recursively, your call of nthPrime' n 2 will expand into
(nthPrime' n 2)+1+1+1+1+1+1+1+1 ...
but the second parameter will never get incremented and your program collects a mass of unevaluated thunks. The evaluation can only happen if the first parameter is reduced to an Int, but your function is in an endless recursion so this will never take place. All the plus ones are stored on the stack, if there is no more space left you'll get a stackoverflow error.
To solve this problem you need to put parranteses around the x+1 so your recursive call will look like this
nthPrime' n (x+1)
Now the parameters gets incremented before it is passed to the recursive call.
This should solve your stackoverflow problem, you can try it out with a smaller number e.g. 101 and you'll get the desired result.
runtime optimization
If you test your program with the original value 10001 you may realize that it still won't finish in a reasonable amount of time.
I won't go into the details of fancy algorithms to solve this problems, if you're interested in them you can easily find them online.
Instead I'll show you were the problem in your code is and show you a simple solution.
The bottleneck is your nthPrime function:
primesTill n = sum [1 | x <- [2..n], checkPrime x]
nthPrime n = nthPrime' n 2
nthPrime' n x
| (primesTill x == n) = x
| otherwise = nthPrime' n (x+1)
This function checks if the number of primes between 2 and x is equal to n. The idea is correct, but it leads to an exponential runtime. The problem is that you recalculate primesTill x for every iteration. To count the primes smaller than x you calculate them all and than sum them up. In the next step for x+1 you forget every thing you know about the numbers between 2 and x and test them all again if they are prime only as a last step you test the if x+1 is prime. Than you repeat this - forget every thing and test all numbers again - until you are finished.
Wouldn't it be great if the computer could remember the primes it has already found?
There are many possibilities to do this I'll use a simple infinite list, if you are interested in other approaches you can search for the terms memoization or dynamic programming.
We start with the list comprehension you used in primesTill:
[1 | x <- [2..n], checkPrime x]
This calculates all primes between 2 and n, but immediately forgets the prime number and replaces it with 1, so the first step will be to keep the actual numbers.
[x | x <- [2..n], checkPrime x]
This gives us a list of all prime numbers between 2 and n. If we had a sufficiently large list of prime numbers we could use the index function !! to get the 10001st prime number. So we need to set n to a really really big number, to be sure that the filtered list is long enough?
Lazy evaluation to the rescue!
Lazy evaluation in haskell allows us to build an infinite list, that is only evaluated as much as needed. If we don't supply an upper bound to a list generator it will build such an infinite list for us.
[x | x <- [2..], checkPrime x]
Now we have a infinite list of all prime numbers.
We can bind it to the a name e.g. primes and use it to define nthPrime
primes = [x | x <- [2..], checkPrime x]
nthPrime n = primes !! n
Now you can compile it with ghc -O2, run it and the result will be promptly delivered to you.

Haskell Mini Function Implementation

I have been trying to take this function and make small implementation using iterate and takeWhile. It doesn't have to be using those functions, really I'm just trying to turn it into one line. I can see the pattern in it, but I can't seem to exploit it without basically making the same code, just with iterate instead of recursion.
fun2 :: Integer -> Integer
fun2 1 = 0
fun2 n
| even n = n + fun2 (n `div` 2)
| otherwise = fun2 (3 * n + 1)
Any help would be great. I've been struggling with this for hours.
Thanks
If you want to do this with iterate, the key is to chop it up into smaller logical parts:
generate a sequence using the rule
ak+1 = ak/2 if ak even
ak+1 = 3ak+1 if ak odd
stop the sequence at aj = 1 (which all do, if the collatz conjecture is true).
filter out the even elements on the path
sum them
So then this becomes:
f = sum . filter even . takeWhile (>1) . iterate (\n -> if even n then n `div` 2 else 3*n + 1)
However, I do think this would be clearer with a helper function
f = sum . filter even . takeWhile (>1) . iterate collatz
where collatz n | even n = n `div` 2
| otherwise = 3*n + 1
This may save you no lines, but transforms your recursion into the generation of data.
Firstly, I agree with tom's comment that there is nothing wrong with your four line version. It's perfectly readable. However, it's occasionally a fun exercise to turn Haskell functions into one liners. Who knows, you might learn something!
At the moment you have
fun 1 = 0
fun n | even n = n + fun (n `div` 2)
| otherwise = fun (3 * n + 1)
You can always convert an expression using guards into an if
fun 1 = 0
fun n = if even n then n + fun (n `div` 2) else fun (3 * n + 1)
You can always convert a series of pattern matches into a case expression:
fun n = case n of
1 -> 0
_ -> if even n then n + fun (n `div` 2) else fun (3 * n + 1)
And finally, you can convert a case expression into a chain of ifs (actually, in general this would require an Eq instance for the argument of your function, but since you're using Integers it doesn't matter).
fun n = if n == 1 then 0 else if even n then n + fun (n `div` 2) else fun (3 * n + 1)
I think you'll agree that this is far less readable than what you started out with.
One liner ;)
fun2 n = if n==1 then 0 else if even n then n + fun2 (n `div` 2) else fun2 (3 * n + 1)
My sense is that short of look-up tables, this function cannot be implemented without recursion because the argument passed in the recursion seems unpredictable (except for n as powers of 2).
On the other hand, rampion helped me learn something new.

How is a recursive prime number checker written in Haskell?

I'm very new to Haskell (and functional programming in general), and I'm trying some basic exercises to try to get an understanding of the language. I'm writing a "naive" prime number checker that divides each number under the input to check if there is any remainder. The only constructs I've learned so far are comprehension lists and recursive functions, so I'm constrained to that. Here's what I'm trying:
isprime 1 = False
isprime 2 = True
isprime n = isprimerec n (n-1)
isprimerec _ 1 = False
isprimerec n t = if (n `rem` t) == 0 then False else isprimerec n (n-1)
The intention is that the user would use isprime n. Then isprime would use isprimerec to determine if the number is prime. It's a pretty round-about way of doing it, but I don't know any other way with my limited knowledge of Haskell.
Here's what happens when I try this:
isprimerec 10 9
Runs forever. I have to use Ctrl+C to stop it.
isprimerec 10 5
Returns False. The else part is never evaluated, so the function never calls itself.
I'm not sure why this is happening. Also, is this anywhere near close to how a Haskell programmer would approach this problem? (And I don't mean checking primality, I know this isn't the way to do it. I'm just doing it this way as an exercise).
The problem is in this line
isprimerec n t = if (n `rem` t) == 0 then False else isprimerec n (n-1)
You use (n - 1) as the second argument where it should be (t - 1). A further point, I think you want the isprimerec _ 1 case = True.
As to your more general question of whether or not this is idiomatic, I think you're on the right track. ghci has a decent command line debugger. I found this by putting your code in a file, loading it, and then issuing the command :break isprimerec. I then called your function and stepped through it with :step.
Your bug is a simple typo; at the end of isprimerec, your second parameter becomes n-1 instead of t-1. But that aside, the function isn't quite idiomatic. Here's the first pass of how I would write it:
isPrime :: (Ord a, Integral a) => a -> Bool
isPrime n | abs n <= 1 = False
isPrime 2 = True
isPrime n = go $ abs n - 1
where go 1 = False
go t = (n `rem` t /= 0) && go (t-1)
(I might call go something like checkDivisors, but go is idiomatic for a loop.) Note that this exposes the bug in your code: once go is local to isPrime, you don't need to pass n around, and so it becomes clearer that recursing on it is incorrect. The changes I made were, in rough order of importance:
I made isprimerec a local function. Nobody else would need to call it, and we lose the extra parameter.
I made the function total. There's no reason to fail on 0, and not really any reason to fail for negative numbers. (Technically speaking, p is prime if and only if -p is prime.)
I added a type signature. It's a good habit to get into. Using Integer -> Bool, or even Int -> Bool, would also have been reasonable.
I switched to interCaps instead of alllowercase. Just formatting, but it's customary.
Except I'd probably make things terser. Manual recursion is usually unnecessary in Haskell, and if we get rid of that entirely, your bug becomes impossible. Your function checks that all the numbers from 2 to n-1 don't divide n, so we can express that directly:
isPrime :: (Ord a, Integral a) => a -> Bool
isPrime n | abs n <= 1 = False
| otherwise = all ((/= 0) . (n `rem`)) [2 .. abs n - 1]
You could write this on one line as
isPrime :: (Ord a, Integral a) => a -> Bool
isPrime n = abs n > 1 && all ((/= 0) . (n `rem`)) [2 .. abs n - 1]
but I wouldn't be surprised to see either of these last two implementations. And as I said, the nice thing about these implementations is that your typo isn't possible to make in these representations: the t is hidden inside the definition of all, and so you can't accidentally give it the wrong value.
Your else branch is broken since it calls isprimerec n (n-1) every time. You probably ought to write isprimerec n (t-1) instead to have it count down.
You could also use a higher-order function all to make this a lot simpler.
isprime 1 = False
isprime n = all (\t -> n `rem` t /= 0) [2..(n-1)]
So OK, you've got the two bugs: your
isprimerec _ 1 = False
isprimerec n t = if (n `rem` t) == 0 then False else isprimerec n (n-1)
should have been
isprimerec _ 1 = True
isprimerec n t = if (n `rem` t) == 0 then False else isprimerec n (t-1)
or, with list comprehension,
isprime n = n>1 && and [ rem n t /= 0 | t <- [n-1,n-2..2] ]
(Internalize that extra parameter t, it was a technicality anyway! -- A-ha, but what's that and, you ask? It's just like this recursive function, foldr (&&) True :: [Bool] -> Bool.)
But now a major algorithmic drawback becomes visually apparent: we test in the wrong order. It will be faster if we test in ascending order:
isprime n = n>1 && and [ rem n t /= 0 | t <- [2..n-1] ]
or even much faster yet if we stop at the sqrt,
isprime n = n>1 && and [ rem n t /= 0 | t <- [2..q] ]
where q = floor (sqrt (fromIntegral n))
or test only by odds, after the 2 (why test by 6, if we've tested by 2 already?):
isprime n = n>1 && and [ rem n t /= 0 | t <- 2:[3,5..q] ]
where q = floor (sqrt (fromIntegral n))
or just by primes (why test by 9, if we've tested by 3 already?):
isprime n = n>1 && and [ rem n t /= 0 | t <- takeWhile ((<= n).(^2)) primes ]
primes = 2 : filter isprime [3..]
And why test the evens when filtering the primes through - isn't it better to not generate them in the first place?
primes = 2 : filter isprime [3,5..]
But isprime always tests division by 2 -- yet we feed it only the odd numbers; so,
primes = 2 : 3 : filter (noDivs (drop 1 primes)) [5,7..]
noDivs factors n = and [ rem n t /= 0 | t <- takeWhile ((<= n).(^2)) factors ]
And why generate the multiples of 3 (i.e. [9,15 ..] == map (3*) [3,5..]), only to test and remove them later? --
{- [5,7..]
== [j+i | i<-[0,2..], j<-[5]] -- loop unrolling, 3x:
== [j+i | i<-[0,6..], j<-[5,7,9]]
== 5:[j+i | i<-[0,6..], j<-[7,9,11]]
== 5:[7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43, ...
\\ [ 9, 15, 21, 27, 33, 39, ...
== [j+i | i<-[0,6..], j<-[ 9 ]]
-}
primes = 2:3:5: filter (noDivs (drop 2 primes))
[j+i | i<-[0,6..], j<-[7, 11]]
We can skip over the multiples of 5 in advance as well (as another step in the Euler's sieve, euler (x:xs) = x : euler (xs `minus` map (x*) (x:xs))):
-- [j+i | i<-[0, 6..], j<-[7, 11]] -- loop unrolling, 5x:
-- == 7:[j+i | i<-[0,30..], j<-[11,13,17,19,23,25,29,31,35,37]]
-- \\ [j+i | i<-[0,30..], j<-[ 25, 35 ]]
primes = 2:3:5:7: filter (noDivs (drop 3 primes))
[j+i | i<-[0,30..], j<-[11,13,17,19,23, 29,31, 37]]
... but that's already going far enough, for now.

Haskell, memoization, stack overflow

I'm working on problem 14 of Project Euler (http://projecteuler.net/problem=14). I'm trying to use memoization so that I save the length of the sequence for a given number as a partial result. I'm using Data.MemoCombinators for that. The program below produces a stack overflow.
import qualified Data.MemoCombinators as Memo
sL n = seqLength n 1
seqLength = Memo.integral seqLength'
where seqLength' n sum = if (n == 1) then sum
else if (odd n) then seqLength (3*n+1) (sum+1)
else seqLength (n `div` 2) (sum+1)
p14 = snd $ maximum $ zip (map sL numbers) numbers
where numbers = [1..max]
max = 999999
The stack overflow should be due to sum+1 being evaluated lazily. How can I force it to be evaluated before each call to seqLength? BTW, is memoization well implemented? I'm more interested in pointing out my Haskell mistakes than in solving the exercise.
The most common ways of forcing evaluation are to use seq, $! or a bang pattern. However sum+1 is not the culprit here. maximum is. Replacing it with the stricter foldl1' max fixes the stack overflow error.
That taken care of, it turns out that your memoization here is no good. Memo.integral only memoizes the first argument, so you're memoizing partial applications of seqLength', which doesn't really do anything useful. You should get much better results without tail recursion so that you're memoizing the actual results. Also, as luqui points out, arrayRange should be more efficient here:
seqLength = Memo.arrayRange (1, 1000000) seqLength'
where seqLength' 1 = 1
seqLength' n | odd n = 1 + seqLength (3*n+1)
| otherwise = 1 + seqLength (n `div` 2)
I'm not familiar with Data.MemoCombinators, so the generic advice is: try seqLength (3*n+1) $! (sum+1) (the same for even n, of course).
Why use MemoCombinators when we can exploit laziness? The trick is to do something like
seqLength x = lengths !! x - 1
where lengths = map g [1..9999999]
g n | odd n = 1 + seqLength (3 * n + 1)
| otherwise = 1 + seqLength (n `div` 2)
which should work in a memoized way. [Adapted from the non-tail-recursive solution by #hammar]
Of course, then seqLength is O(n) for the memoized case so it suffers less performance. However, this is remediable! We simply take advantage of the fact that Data.Vector is streamed and has O(1) random access. The fromList and map will be done at the same time (as the map will simply produce thunks instead of the actual values because we are using a boxed vector). We also fallback on a non-memoized version since we can't possibly memoize every possible value.
import qualified Data.Vector as V
seqLength x | x < 10000000 = lengths V.! x - 1
| odd x = 1 + seqLength (3 * n + 1)
| otherwise = 1 + seqLength (n `div` 2)
where lengths = V.map g $ V.fromList [1..99999999]
g n | odd n = 1 + seqLength (3 * n + 1)
| otherwise = 1 + seqLength (n `div` 2)
Which should be comparable or better to using MemoCombinators. Don't have haskell on this computer, but if you want to figure out which is better, there's a library called Criterion which is excellent for this sort of thing.
I think using Unboxed Vectors could actually give better performance. It would force everything at once when you evaluate one item (I think) but you need that anyway. Hence you could then just run a foldl' max to get a O(n) solution that should have less constant overhead.
If memory serves, for this problem you don't need memoization at all. Just use foldl' and bang patterns:
snd $ foldl' (\a n-> let k=go n 1 in if fst a < ....
where go n !len | n==1 = ....
Compile with -O2 -XBangPatterns . It's always better to run stadalone as running compiled code in ghci can introduce space leaks.

Printing a result during a recursion in haskell

I am beginning to learn Haskell and am making a program to do the iterative process:
n -> n/2 (for even n)
n -> 3n+1 (for odd n)
So I got this far:`
chain n | n == 0 = error "What are you on about?"
| n == 1 = error "Finished"
| rem n 2 == 0 = chain (n `div` 2)
| rem n 2 /= 0 = chain (3 * n + 1)
`
Will this work?
But it only does the calculations behind the scenes, is there any way to make it display or export as list the result for n on each iteration until it reaches 1 so I can find the length of the list later?
On a side note, is there any way to make GHCi begin in a specific folder ?(I'm using windows)
You could have it return a list of the results in the "chain" like this:
chain n | n == 0 = error "What are you on about?"
| n == 1 = []
| rem n 2 == 0 = (n `div` 2) : chain (n `div` 2)
| otherwise = (3 * n + 1) : chain (3 * n + 1)
Now you'll get results like these:
*Main> chain 3
[10,5,16,8,4,2,1]
*Main> chain 7
[22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1]
Yes, certainly. There's even a function from the Data.List module that captures this usage pattern.
import Data.List (unfoldr)
chain 0 = []
chain n = unfoldr f n
where
f 1 = Nothing
f n = let n' | even n = n `div` 2
| otherwise = 3 * n + 1
in Just (n', n')
The type of unfoldr is: (b -> Maybe (a, b)) -> b -> [a]
b is the state variable that used to generate the list. The function supplied as the first argument to unfoldr should either returns Nothing (which means terminate the list) or Just (b, a) where a is the element to add to the list, and b is the new state variable.
is there any way to make it display or export as list the result for n on each iteration until it reaches 1
You can use the Debug.Trace.trace to print logging messages to stdout as values are evaluated. Good for quick debugging.
You will notice that the two earlier answers use the paradigm of "build the whole list, and then output it at the end" rather than "output one element at a time". This is the functional way of doing things.
If you really want to do it in an imperative style, you have to use monadic programming, which is a more advanced topic. Here's an example (don't worry if you can't understand everything that's going on ... monads are quite mysterious and magical):
import Control.Monad.Writer
chain :: Int -> (String, [Int])
chain = runWriter . chain'
where
chain' 0 = return "Failure"
chain' 1 = do
tell [1] -- write 1
return "Success" -- finished
chain' n = do
-- write n
tell [n]
-- calculate next n and recurse
if even n
then chain' $ n `div` 2
else chain' $ 3 * n + 1
Which gives results like:
*Main> chain 3
("Success",[3,10,5,16,8,4,2,1])
But, as you can see, the writer monad still just generates the list behind the scenes.
This might seem inefficient. What if you want to print a list of 1,000,000 elements? Do you really have to generate the whole list upfront? In fact, Haskell's lazy semantics mean that, whenever possible, Haskell will compile your "build the whole thing upfront and then print it out" code into "only generate and output one element at a time" code.
The function should just return the list of found elements. This list can be inspected further later on:
chain 0 = error "No no no."
chain 1 = [1]
chain n
| rem n 2 == 0 = n : chain (n `div` 2)
| otherwise = n : chain (3 * n + 1)
Here [1] is a list containing just 1 and : is a list constructor that adds the element on the left to the list on the right.
The list constructed by chain can then be displayed or used with other functions:
*Main> chain 5
[5,16,8,4,2,1]
*Main> length (chain 31)
107

Resources