Распознавание хвостовой рекурсии

Я пытаюсь изучить Haskell и наткнулся на следующее:

myAdd (x:xs) = x + myAdd xs
myAdd null = 0

f = let n = 10000000 in myAdd [1 .. n]

main = do
 putStrLn (show f)

При компиляции с помощью GHC это приводит к переполнению стека. Как программист на C / C ++, я ожидал, что компилятор выполнит оптимизацию хвостового вызова.

Мне не нравится, что мне придется «помогать» компилятору в таких простых случаях, но какие есть варианты? Я думаю, что разумно потребовать, чтобы приведенный выше расчет выполнялся без использования памяти O (n) и без обращения к специализированным функциям.

Если я не смогу сформулировать свою проблему естественным образом (даже для такой игрушечной задачи, как эта) и ожидать разумной производительности с точки зрения времени и пространства, большая часть привлекательности Haskell будет потеряна.

8
задан AndrewC 19 December 2012 в 02:01
поделиться