我们都知道(或者应该知道) Haskell 默认是懒惰的。在必须对其进行计算之前,不对任何内容进行计算。那么,什么时候必须对某些东西进行评估呢?Haskell 在某些方面一定很严格。我把这些称为“严格点”,尽管这个特殊的术语并不像我想象的那么普遍。我认为:
在哈斯克尔,只有的降低(或评估)发生在严格的点上。
所以问题是: 我的直觉告诉我,main
、 seq
/bang 模式、模式匹配和任何通过 main
执行的 IO
动作都是主要的严格点,但我真的不知道为什么我知道这些。
(另外,如果它们不被称为“严格点”,那么它们被称为什么 是?)
我想一个好的答案将包括一些关于 WHNF 等的讨论。我还想它可能会涉及到 lambda 微积分。
编辑: 关于这个问题的其他想法。
正如我对这个问题的反思,我认为在严格点的定义中加入一些东西会更清楚。严格点可以有不同的 背景和不同的 深度(或严格)。回到我的定义“哈斯克尔的减少只发生在严格点上”,让我们在这个定义中添加这样一个条款: “只有当其周围环境被评估或减少时,才会触发严格点。”
那么,让我试着给你一个我想要的答案。main
是一个严格点。它被特别指定为其上下文的主要严格点: 程序。当程序(main
的上下文)被计算时,main 的严格点被激活。主要的深度是最大的: 它必须充分评估。Main 通常由 IO 操作组成,这些操作也是严格点,其上下文是 main
。
现在你可以尝试: 用这些术语讨论 ABc0和模式匹配。解释函数应用的细微差别: 它是如何严格的?怎么不是呢?那 deepseq
呢?let
和 case
报表?unsafePerformIO
?Debug.Trace
?顶级定义?严格的数据类型?爆炸模式?等等。这些项目中有多少可以用序列或模式匹配来描述?