简体   繁体   English

为什么这个Haskell过滤器会终止?

[英]Why does this Haskell filter terminate?

I don't understand why the following Haskell code terminates under GHCi: 我不明白为什么以下Haskell代码在GHCi下终止:

let thereExists f lst = (filter (==True) (map f lst)) /= []
thereExists (\x -> True) [1..]

I did not expect the call to filter to ever complete, given that its second argument is infinite, and I did not think the comparison could take place until the lhs was completely calculated. 我没想到过滤器的调用永远不会完成,因为它的第二个参数是无限的,我不认为比较可能发生在lhs完全计算之前。 What's happening? 发生了什么?

The comparison can take place before the LHS is completely calculated. 比较可以在完全计算LHS之前进行。 As soon as filter has produced one element, /= is able to conclude that the list can't possibly be equal to [] and immediately return True . 一旦filter生成了一个元素, /=就能够得出结论列表不能等于[]并立即返回True

/= on lists is implemented something like this: 列表上的/=实现如下:

(/=) :: Eq a => [a] -> [a] -> Bool
[] /= []         = False
[] /= (y:ys)     = True
(x:xs) /= []     = True
(x:xs) /= (y:ys) = (x /= y) || (xs /= ys)

Since Haskell is lazy, we will only evaluate the arguments as much as is necessary to choose which right hand side we will use. 由于Haskell是懒惰的,我们只会根据需要选择哪些参数来选择我们将使用的右侧。 Evaluation of your example goes something like this: 您的示例评估如下:

    filter (== True) (map (\x -> True) [1..]) /= []
==> (True : (filter (== True) (map (\x -> True) [2..]))) /= []
==> True

As soon as we know that the first argument of /= is (1 : something) , it matches the third equation for /= in the code above, so we can return True . 一旦我们知道/=的第一个参数是(1 : something) ,它就匹配上面代码中的/=的第三个等式,所以我们可以返回True

However, if you try thereExists (\\x -> False) [1..] it will indeed not terminate, because in that case filter will never make any progress towards producing a constructor we can match against. 但是,如果你尝试使用thereExists (\\x -> False) [1..]它确实不会终止,因为在这种情况下, filter永远不会在生成我们可以匹配的构造函数方面取得任何进展。

     filter (== True) (map (\x -> False) [1..]) /= []
==>  filter (== True) (map (\x -> False) [2..]) /= []
==>  filter (== True) (map (\x -> False) [3..]) /= []
...

and so on infinitely. 等等无限。

In conclusion, thereExists on an infinite list can return True in finite time, but never False . 总之, thereExists无限的名单上可以返回True在有限的时间,但从来没有False

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM