Haskell:使用严格性的指南

Posted

技术标签:

【中文标题】Haskell:使用严格性的指南【英文标题】:Haskell: Guidelines for using Strictness 【发布时间】:2014-02-12 06:59:24 【问题描述】:

在 Haskell 中何时使用严格性是否有任何推荐指南?

例如,我正在查看 tagsoup 库。他们的数据结构之一定义如下:

data Tag str    
    = TagOpen str [Attribute str]
    | TagClose str
    | TagText str
    | TagComment str
    | TagWarning str
    | TagPosition !Row !Column 

type Row = Int 
type Column = Int

那么,他们究竟基于什么因素决定 TagPosition 应该严格?对此有什么推荐的指导方针吗?

【问题讨论】:

一个列表是非严格的并且代表一个流(根据需要评估它的元素是有意义的)。一个 Int 代表一个数字。懒惰地评估它仍然有意义(例如,它可能代表您并不真正需要的流的长度)。简而言之:这取决于应用程序。 @d8d0d65b3f7cf42 实际上,如果我们谈论像 Int 这样的东西,如果你从不使用这个值,那么偷懒会更快吗?数值运算非常快,我不确定这与生成 thunk 的速度相比如何。这还没有考虑到内存成本。 @DavidYoung 正如我所说,这不太可能。但如果你把它当作一个挑战,我相信有可能想出一个更快的场景。总是有可能有一个 Int 字段,您在该字段上的计算量很少,但计算成本极高,而且您很少需要。那么懒惰的Int 会更快。 【参考方案1】:

对于简单的非结构化数据类型,例如IntDouble,将它们转换为严格字段通常是一个不错的默认设置。这使得他们的空间消耗非常可预测(并且恒定)。虽然执行不必要的计算可能会导致性能下降,但这通常不太可能。例如,跟踪位置通常非常简单且成本低廉,因此在性能方面没有什么可害怕的,而且具有可预测的空间行为更为重要。

使简单类型严格的另一个优点是它们通常可以解包,即直接存储在构造函数中,而不是通过额外的间接(有编译指示或编译器标志)。对于小型类型,这通常是一个优势。

对于列表或树等结构化数据类型,情况要复杂得多。一个简单的! 在这里很少有帮助,因为它只会强制执行 WHNF。评估的列表或树在空间方面也很容易比未评估的 thunk 更昂贵。然而,有时对这些数据进行严格也是有意义的。在这种情况下,您通常会使用一个函数(所谓的智能构造函数)包装构造函数,该函数通过在适当的位置调用deepseq 来建立严格不变量。

【讨论】:

以上是关于Haskell:使用严格性的指南的主要内容,如果未能解决你的问题,请参考以下文章

是否有使用严格评估的 Haskell 编译器或预处理器?

Haskell - 严格与非严格与 foldl

Haskell趣学指南

Haskell严格的字段

有人可以向我解释或将我链接到一个很好的指南,该指南解释了让和在 Haskell 中的位置 [关闭]

Haskell“资源缩减”