【问题标题】:Timing out pure functions纯函数超时
【发布时间】:2012-04-09 09:52:10
【问题描述】:

如何“杀死”耗时过长的纯计算?我试过了

import System.Timeout

fact 0 = 1
fact n = n * (fact $ n - 1)

main = do maybeNum <- timeout (10 ^ 7) $ (return . fact) 99999999
          print maybeNum

但是,这不起作用。将 (return . fact) 99999999 替换为像 getLine 这样的“真实” IO 函数,这将按预期工作。

【问题讨论】:

  • 有趣的是,如果 fact 成为“真正的” IO 操作 (fact 0 = return 1; fact n = (n *) `fmap` (fact $ n - 1)),那么 timeout 也会按预期工作。
  • @MatveyAksenov:我认为这并不是因为该函数是一个真正的 IO 动作,而是因为它的递归通过 fmap 移动到了 IO monad。
  • 如果您需要超时任意和潜在的恶意代码,请确保针对非常简单的非分配循环进行测试,例如let x = x in xlet x () = x () in x ().

标签: haskell timeout purely-functional


【解决方案1】:

重点是

return (fact 999999999)

立即返回并且不会触发超时。它返回一个稍后将被评估的 thunk。

如果你强制评估返回值,

main = do maybeNum <- timeout (10 ^ 7) $ return $! fact 99999999
          print maybeNum

它应该触发超时(如果您提供的堆栈足够大,以便在堆栈溢出之前发生超时)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-19
    • 2012-06-18
    • 2019-10-05
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 2020-06-09
    相关资源
    最近更新 更多