tl;dr
事实难道不是这样吗20 < length $ take 10 $ whatever
需要whatever
成功地对列表进行模式修补(至少[]
or (_:_)
)“缺乏”懒惰?
或者,换句话说,为什么不(20 >) . length . take 10 === const True
,因此将它们中的任何一个应用于任何事物都不需要对论证进行任何评估?
Is (20 >) . length . take 10 !== const True
有必要吗?还是设计选择?无论哪种情况,为什么?
Foreword
这是后续我之前的问题 https://stackoverflow.com/q/72133599/5825294.
在那里我问了为什么fix https://hackage.haskell.org/package/base-4.16.1.0/docs/Data-Function.html#v:fix error
prints *** Exception:
反复地、无限地。
答案是令人满意的。
我的思考
然而,我玩了一下ghci
并意识到take 0 $ fix error
预期回报""
, and length $ take 0 $ fix error
回报0
.
另一方面,以下内容打印*** Exception:
无限流:
20 > (length $ take 10 $ fix error)
我明白那个if即使是其中的一种元素fix error
被计算(实际上尝试),结果就是这样,但我的问题是:为什么首先需要对它们中的任何一个进行评估,在那个特定的表达中?毕竟,length $ take 10 $ whatever
不能是其他<= 10
, hence < 20
,因此表达式应计算为True
.
事实上,我看到了20 > (length $ take 10 $ [fix error])
立即返回True
。也许重点是take 10
预计将致力于[a]
, 所以length $ take 10 $ [fix error]
不需要评价fix error
确保它正在工作[a]
。确实,我已经验证过20 > (length $ take 10 $ undefined)
也会出现错误(即使不是无限重复的错误),而20 > (length $ take 10 $ [undefined])
返回与True
.
也许就是这样威廉·范·翁塞姆在此评论中的意思是 https://stackoverflow.com/questions/72133599/what-is-fix-in-haskell-and-why-does-fix-error-print-an-infinite-string-and/72133643?noredirect=1#comment127469056_72133643.
无论如何,因为我可以将上面的表达式写为
((20 >) . length . take 10) $ fix error
我很想说
(20 >) . length . take 10 === const True
因此我认为这是合理的((20 >) . length . take 10) $ fix error
回来True
就像const True $ fix error
回报True
.
但事实并非如此。为什么?