haskell中列表的强制严格性

haskell中列表的强制严格性,haskell,data-structures,lazy-evaluation,evaluation,strictness,Haskell,Data Structures,Lazy Evaluation,Evaluation,Strictness,我做了一个非常耗时的算法,结果是生成一个短字符串。当我尝试打印它(通过putStrLn)时,它会逐个字符显示在屏幕上。我确实理解了为什么会发生这种情况,我试图在实际打印之前强制对字符串进行评估 myPrint !str = putStrLn str 但这帮不了什么忙。当我在调试中运行程序时,我注意到!str仅对第一个字符强制求值 有人知道为什么会这样,以及如何处理吗?(!)翻译成seq,它的计算结果严格来说是-,也就是说,它只计算最外层的构造函数。要进行更深入的评估,您需要seq的“深层”形式

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

myPrint !str = putStrLn str
但这帮不了什么忙。当我在调试中运行程序时,我注意到!str仅对第一个字符强制求值

有人知道为什么会这样,以及如何处理吗?

(!)
翻译成
seq
,它的计算结果严格来说是-,也就是说,它只计算最外层的构造函数。要进行更深入的评估,您需要
seq
的“深层”形式

这被称为
deepseq


它位于。

每字符打印有什么问题?我喜欢这种方法,正如你所见,当程序评估你的东西时。这将是一个工具,它只是看起来有点难看。但出于调试的目的,我完全同意,它可能是有用的。这将是一种工作,但仅当您实际需要对
()
进行评估时,例如
seq(seqList xs)(doSomethingWith xs)
。即使这样,它也只会强制列表的脊椎,而不会强制单个元素(并非仅强制脊椎没有用处)。这可能是棘手的严格正确!另外,我想你的意思是最后一行中的
seqList
。另一种方法是对列表执行一些无用的计算:length$filter(=“?”)list。为了澄清,对于列表,“最外面的构造函数”是最左边的
,这就解释了为什么它只强制使用字符串的第一个字符
seqList :: [a] -> ()
seqList [] = ()
seqList (x:xs) = strictList xs