Как запретить QuickCheck перехватывать все исключения?

Библиотека QuickCheck, по-видимому, перехватывает все исключения, возникающие при тестировании свойства. В частности, такое поведение не позволяет мне установить ограничение по времени для всего вычисления QuickCheck. Например:

module QuickCheckTimeout where

import System.Timeout (timeout)
import Control.Concurrent (threadDelay)
import Test.QuickCheck (quickCheck, within, Property)
import Test.QuickCheck.Monadic (monadicIO, run, assert)

-- use threadDelay to simulate a slow computation
prop_slow_plus_zero_right_identity :: Int -> Property
prop_slow_plus_zero_right_identity i = monadicIO $ do
  run (threadDelay (100000 * i))
  assert (i + 0 == i)

runTests :: IO ()
runTests = do
  result <- timeout 3000000 (quickCheck prop_slow_plus_zero_right_identity)
  case result of
    Nothing -> putStrLn "timed out!"
    Just _  -> putStrLn "completed!"

Поскольку QuickCheck перехватывает все исключения, тайм-аут прерывается: на самом деле вычисления не прерываются! Вместо этого QuickCheck рассматривает свойство как неисправное и пытается уменьшить ввод, вызвавший сбой. Затем этот процесс сжатия не запускается с ограничением по времени, в результате чего общее время, используемое для вычислений, превышает установленный предел времени.

Можно подумать, что я могу использовать комбинатор QuickCheck in для ограничения времени вычислений. (within рассматривает свойство как неудавшееся, если оно не завершается в течение заданного срока.) Однако within не совсем то, что мне нужно, поскольку QuickCheck по-прежнему пытается уменьшить ввод, вызвавший сбой, а этот процесс может занять слишком много времени. (В качестве альтернативы мне могла бы подойти версия внутри, которая предотвращает попытки QuickCheck сжать входные данные до свойства, которое не удалось, поскольку оно не завершилось в течение заданного срока.)

Как запретить QuickCheck перехватывать все исключения?

7
задан Brad Larsen 3 March 2012 в 21:48
поделиться