Чи ответил на один бит вопроса, который, я думаю, является основной проблемой, но есть кое-что еще, что беспокоит меня.Когда вы говорите 10**9
, вы получаете число с плавающей запятой (потому что **
- это "дробное" возведение в степень).И затем вы используете равенство с плавающей запятой для проверки базового случая вашей рекурсии.
summ 1 = ...
Проблема в том, что это возможно, и, по мере того, как аргумент становится больше, вероятно, что из-за числовой ошибки вы просто пропустите базовый случай и опуститесь в отрицательные значения навсегда.
summ 4 = ... summ 3
summ 3 = ... summ 2.000001
summ 2.000001 = ... summ 1.000001
summ 1.000001 = ... summ 0.000001 -- BASE CASE MISSED!
summ 0.000001 = ... summ (-1.000001)
summ (-1.000001) = ... summ (-2.000001)
и так далее.Если вы не получили переполнение стека при вызовах 10 9 , вы наверняка получите бесконечное количество.
Вы должны либо определить свою функцию на целых числах, чтобы не было ошибки округления
summ :: Int -> Double
summ 1 = 1
summ n = 1 / (fromIntegral n ** 2) + summ (n - 1)
-- ^^^^^^^^^^^^
-- conversion necessary to go from Int to Double
main = ... print (summ (10 ^ 9))
-- ^^^^^^
-- use integral exponentiation (^) instead of (**)
или используйте более щадящий базовый вариант
summ :: Double -> Double
summ n | n <= 1 = 1
summ n = 1 / (n ** 2) + summ (n - 1)
В любом случае, вам определенно следует принять предложение Чи сделать это в стиле аккумулятора, а также обязательно поставить подпись типа.
Вот больше о том, как вы получаете переполнение стека в Haskell , если вам интересно.