为什么“ mask_”会抵消“超时”?

问题描述

| 我终于能够追踪到一个奇怪的错误,直到(至少对我而言)
mask
timeout
之间令人惊讶的相互作用:
import System.Timeout
import Control.Exception

ack :: Int -> Int -> Int
ack m n | m == 0,n >= 0  = n + 1
        | m >  0,n == 0  = ack (m - 1) 1
        | m >  0,n >  0  = ack (m - 1) (ack m (n - 1))

tryack :: Int -> Int -> IO (Maybe Int)
tryack m n = timeout 100000 {- uS -} $ evaluate $ ack m n

main :: IO ()
main = do
  a <- tryack 3 11
  print a -- Nothing

  b <- mask_ $ tryack 3 11
  print b -- Just 16381 after a few seconds
这让我颇为“非组成性”交互,因为这意味着如果库内部使用
timeout
,则在调用链中某个位置外部应用的
mask
可能会导致库发生故障。 那么这是ѭ1实施中的(已知的)缺陷,还是故意的?     

解决方法

        
mask_
是做什么的?   在掩盖了异步异常的情况下执行IO计算。也就是说,任何试图在当前线程中使用Control.Exception.throwTo引发异常的线程都将被阻塞,直到再次取消屏蔽异步异常为止。
timeout
是做什么的?   包装IO计算以超时并在n微秒(1/10 ^ 6秒)内没有结果的情况下不返回任何内容。如果在超时到期前有结果可用,则仅返回a。 ...一个棘手的实现细节是如何中止IO计算的问题。该组合器在内部依赖异步异常。 所以...
mask_
阻止
timeout
传递其异常。就是这样。 您只是不能使用
mask
而拥有
timeout
工作。 也许更好的方法是使用处理程序来捕获除
timeout
使用的异常以外的任何内容?     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...