我想使用QuickCheck测试函数以确保它终止(没有无限递归,没有抛出异常等)。这就是我现在所做的事情:
f :: Int -> Int -> Int
prop_fTerminates :: Int -> Int -> Bool -- say
prop_fTerminates x y = f x y `seq` True
是否有更好的(更具表现力和惯用语)的方式?
答案 0 :(得分:7)
这是halting problem。没有能够告诉您函数是否终止的算法。
特别是,如果您愿意等待足够长的时间,可能能够得到肯定的结果(即如果该功能终止,这个命题会告诉您)。但只是等待,你永远不会知道这个函数没有终止和这个函数还没有终止之间的区别。
您可以执行类似的检查此功能是否在时间T 中终止,这可能适合您的需要。
编辑如上所述,您的功能无法满足您的要求。考虑
> let f = 1:f
> f `seq` True
True
原因是seq
仅评估为weak head normal form。相反,您可以使用deepseq
来深入评估数据结构,
> import Control.DeepSeq (deepseq)
> f `deepseq` True
* never returns *
答案 1 :(得分:4)
我可能不会打扰,我只是测试其输出的其他属性。
以任何方式检查f x y
输出的任何属性都将至少与prop_fTerminates
进行一样的终止检查,所以为什么要浪费时间加倍检查?
如果由于某种原因“f x y终止”是你可以测试f
的唯一属性,那么你所得到的似乎是合理的。