Search code examples
haskellrecursionstack-overflowguard

Haskell recursion stack overflow


I am pretty new to Haskell, so sorry for the question. But - how to get rid of the endless recursion and not been overflown. This is the code:

foo :: Integer -> Integer
foo x
    | x == 1         = 1
    | x <= 0         = error "negative number or zero"
    | odd x          = foo 3 * x + 1
    | x `mod` 2 == 0 = foo x `div` 2
    | otherwise      = x

EDIT:

foo :: Integer -> (Integer, Integer)
foo x
    | x == 1         = (1, z) 
    | x <= 0         = error "negative number or zero"
    | odd x          = foo  (3 * x + 1) . inc z
    | even x         = foo  (x `div` 2) . inc z
    | otherwise      = (x, z)
  where z = 0

inc :: Integer -> Integer
inc i = i + 1

I believe that the code is self-explanatory, but yet : If x is even then divide it with 2 otherwise 3*x + 1. This is part of the famous Collatz problem.


Solution

  • Function application has higher precedence than many other operations, so foo 3 * x + 1 is actually calling foo 3, then multiplying that result by x and adding 1, which looks like where your infinite loop might be.

    Changing it to the following should fix that:

    | odd x          = foo $ 3 * x + 1
    | x `mod` 2 == 0 = foo $ x `div` 2