Как я могу использовать функцию тайм-аута Haskell (в System.Timeout), чтобы остановить быстрые вычисления? - PullRequest
9 голосов
/ 25 марта 2019

Функция тайм-аута в System.Timeout иногда не может остановить бесконечное вычисление.

Например,

timeout 1000 $ print $ length [0..]

возвращает Nothing, как и ожидалось, поскольку время ожидания прерывает бесконечное вычисление. Но

timeout 1000 $ print $ length $ cycle [1,2,3]

петли навсегда.

Это на Mac с использованием ghc или ghci 8.6.4.

Я ожидаю, что второй пример будет вести себя как первый, прерывая бесконечное вычисление через 1 миллисекунду и возвращая Nothing. Вместо этого второй пример зависает.

1 Ответ

4 голосов
/ 25 марта 2019

Вы можете использовать свою собственную, не разделяющую реализацию, cycle:

> _Y g = g (_Y g)
_Y :: (t -> t) -> t

> take 10 . _Y $ ([1,2,3] ++)
[1,2,3,1,2,3,1,2,3,1]
it :: Num a => [a]

> timeout 100000 . print . length . _Y $ ([1,2,3] ++)
Nothing
it :: Maybe ()
(0.11 secs, 152470624 bytes)

_Y, конечно, выделит бесконечный, растущий список, в отличие от общего доступа cycle, который эквивалентен fix ([1,2,3] ++), который создает реальный циклический список в памяти:

> timeout 100000 . print . length . fix $ ([1,2,3] ++)
<<<hangs>>>

Смотри также:

...