Почему оптимизация хвостового вызова не используется в этой программе на Haskell? - PullRequest
6 голосов
/ 14 марта 2012

Следующая программа удаляет стек:

__find_first_occurrence :: (Eq b) => b -> [b] -> Int -> Int
__find_first_occurrence e [] i = -1
__find_first_occurrence e (x:xs) i
    | e == x = i
    | otherwise = __find_first_occurrence e xs (i + 1)

find_first_occurrence :: (Eq a) => a -> [a] -> Int
find_first_occurrence elem list =   
    __find_first_occurrence elem list 0

main = do
    let n = 1000000
    let idx = find_first_occurrence n [1..n]
    putStrLn (show idx)

Сбой при

Переполнение стека: текущий размер 8388608 байт.Используйте `+ RTS -Ksize -RTS 'для его увеличения.

Однако, насколько я понимаю, возможный рекурсивный вызов __find_first_occurrence - это последнее, что оценивается __find_first_occurrence, поэтомудолжна быть возможна оптимизация хвостового вызова.

1 Ответ

15 голосов
/ 14 марта 2012

Используется оптимизация хвостового вызова, но выражения (i+1) преобразуются, и их оценка в конце приводит к переполнению стека.

...