Как избежать переполнения стека в Haskell?

Haskell не поддерживает циклическое выполнение вычислений, вместо этого он предлагает использовать алгоритмы рекурсии. Но такой подход приводит к увеличению стека и даже его переполнению. Считаю, что к решению этой проблемы в целом нужен подход. Вот образец. Я хотел знать, сколько раз getClockTime может быть вызван за 5 секунд:

import System.Time

nSeconds = 5

main = do
    initTime <- totalPicoSeconds `fmap` getClockTime
    doWork initTime 1
    where
    doWork initTime n = do
        currTime <- totalPicoSeconds `fmap` getClockTime
        if (currTime - initTime) `div` 10 ^ 12 >= nSeconds
            then print n
            else doWork initTime (n+1)

totalPicoSeconds :: ClockTime -> Integer
totalPicoSeconds (TOD a b) = a * 10 ^ 12 + b

Программа работает 5 секунд, но в итоге я получаю:

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

Ручное управление размером стека может помочь в конкретном случае, но если я захочу запустить этот алгоритм в течение 10 секунд, он может снова переполниться. Так что это не выход. Как мне заставить этот код работать?

18
задан Dmitry Bespalov 29 February 2012 в 19:14
поделиться