列表理解与参数不终止

时间:2014-09-25 01:47:57

标签: haskell list-comprehension

我想说我想找到(Integer, Integer)的列表,其中i和j是&gt; = 2,i + j + 2*i*j < 100

ghci> take 10 [ (i, j) | i <- [2..], j <- [2..], i * j + 2*i*j < 100]
[(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8),(2,9),(2,10),(2,11)]

然而,当我更改此函数以接受参数n(而不是100)时,它在约15秒后不会终止。

ghci> let f n = take 10 [ (i, j) | i <- [2..], j <- [2..], i * j + 2*i*j < n]

ghci> f 5
Interrupted.

1 个答案:

答案 0 :(得分:8)

如果您拨打f 100而不是f 5,您将获得与第一个示例相同的结果。问题不在于它是一个功能;事实上,当过滤器永远不会返回那么多元素时,你试图提取过滤的无限列表的前10个元素。

i没有大于或等于2的j3*i*j < 5值,因此n=5的返回列表应为空。但是,在Haskell检查ij的所有可能值之前,它无法确定它是否为空。如上所述,这是无限多种可能性。由于它永远不会耗尽可能的输入,并且永远不会达到所需的十个输出,因此它永远不会终止。

要注意的另一件事是n=100问题的前十个答案都有i=2。如果您尝试中间的数字,例如50,您可以观看该函数生成该案例的正确答案的第一部分 - 特别是在n=50的情况下,具有i的七个元素等于2.但在那之后,尽管有超过所需的三个额外的解决方案来获得十个元素,它就会挂起。那是因为这些额外的解决方案都有i > 2。哈斯克尔并没有找到它们,因为它永远不会过去看第一个无限的&#34; i为2且j为任意数字的情况。