2015-05-24 5 views
0

Я довольно новичок в Haskell, так что извините за вопрос. Но - как избавиться от бесконечной рекурсии и не переполняться. Это код:Переполнение стека переполнения Haskell

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 

Я считаю, что код само за себя, но все же: если х четно, то разделить его с 2 в противном случае 3 * х + 1. Это часть знаменитой проблемы Collatz.

+1

Вы также можете использовать 'even' вместо' 2' мод испытания. И похоже, что ваш случай «иначе» никогда не будет достигнут. –

+0

В вашем редактировании выражение типа 'f x. g y' ассоциируется как '(f x). (g y) 'вместо' (f x. g) y', потому что приложение функции привязывается сильнее, чем любой оператор. Вы можете использовать '$' здесь (на самом деле, вы можете смешивать '' 'с' .'), но вы также можете просто сделать круглые скобки явными и не использовать '.' или' $ '. –

ответ

5

Функция приложение имеет более высокий приоритет, чем многие другие операции, так foo 3 * x + 1 на самом деле вызов foo 3, то умножив результат на x и добавление 1, который выглядит как, где ваш бесконечный цикл может быть.

Изменение его следующее должно исправить:

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

Не могли бы вы объяснить, что такое '' '' '? – user8

+2

Вы также можете написать это как 'f (3 * x + 1)'. См. [Этот пост] (http://stackoverflow.com/questions/940382/haskell-difference-between-dot-and-dollar-sign) для более длинного описания '$'. –

+0

Когда я хочу увеличить его с помощью '.', чтобы подсчитать количество применений' foo', что еще мне делать? Он находится в части редактирования. – user8

Смежные вопросы