Я довольно новичок в 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.
Вы также можете использовать 'even' вместо' 2' мод испытания. И похоже, что ваш случай «иначе» никогда не будет достигнут. –
В вашем редактировании выражение типа 'f x. g y' ассоциируется как '(f x). (g y) 'вместо' (f x. g) y', потому что приложение функции привязывается сильнее, чем любой оператор. Вы можете использовать '$' здесь (на самом деле, вы можете смешивать '' 'с' .'), но вы также можете просто сделать круглые скобки явными и не использовать '.' или' $ '. –