【问题标题】:Forced strictness for lists in haskellhaskell中列表的强制严格性
【发布时间】:2011-07-30 07:20:27
【问题描述】:

我做了一个非常耗时的算法,结果是一个短字符串。当我尝试打印它(通过 putStrLn)时,它一个字符一个字符地出现在屏幕上。我确实理解为什么会发生这种情况,并且我尝试在实际打印之前强制评估字符串。

myPrint !str = putStrLn str

但这帮助很小。当我在调试中运行程序时,我注意到 !str 仅对第一个字符进行强制评估。

有谁知道这是为什么,以及如何处理?

【问题讨论】:

  • 每字符打印有什么问题?如您所见,我喜欢这种方法,当程序评估您的东西时。
  • 这将是一个工具,只是看起来有点丑。但出于调试目的,我完全同意,它可能很有用。

标签: haskell data-structures lazy-evaluation evaluation strictness


【解决方案1】:

(!) 转换为seq,其计算结果严格为Weak Head Normal Form——也就是说,它只计算最外层的构造函数。要进行更深入的评估,您需要seq 的“深度”形式。

这被称为deepseq

它在the deepseq package

【讨论】:

  • 澄清一下,对于列表,“最外层构造函数”是最左边的:,这就解释了为什么它只强制字符串的第一个字符。
  • 什么是弱头范式的更详细的说明是here
【解决方案2】:
seqList :: [a] -> ()
seqList [] = ()
seqList (x:xs) = strictList xs

【讨论】:

  • 这会起作用,但前提是您确实需要评估 (),例如seq (seqList xs) (doSomethingWith xs)。即使那样,它也只会强制列表的脊椎,而不是单个元素(并不是仅仅强制脊椎没有用)。使严格性正确可能很棘手!
  • 另外,我想你的意思是最后一行的seqList
  • 另一种方法是对列表进行一些无用的计算:length $ filter (=="?") list。
猜你喜欢
  • 1970-01-01
  • 2014-02-12
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
相关资源
最近更新 更多