How can I use the Haskell timeout function (in System.Timeout) to halt runaway computations?

坚强是说给别人听的谎言 提交于 2019-12-08 17:34:48

问题


The timeout function in System.Timeout sometimes fails to halt an infinite computation.

For example,

timeout 1000 $ print $ length [0..]

returns Nothing as expected because the timeout interrupts the infinite computation. But

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

loops forever.

This is on a Mac, using ghc or ghci 8.6.4.

I expect the second example to behave like the first, interrupting the infinite computation after 1 millisecond and returning Nothing. Instead, the second example hangs.


回答1:


You can use your own, non-sharing implementation of 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 will of course allocate an infinite, growing list, unlike the sharing cycle which is equivalent to fix ([1,2,3] ++) which creates an actual cyclic list in memory:

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

See also:

  • How can I stop infinite evaluation in GHCi?


来源:https://stackoverflow.com/questions/55336948/how-can-i-use-the-haskell-timeout-function-in-system-timeout-to-halt-runaway-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!