qua*_*dev 12 haskell strict lazy-evaluation seq
这个FAQ说明了这一点
seq运算符是
Run Code Online (Sandbox Code Playgroud)seq :: a -> b -> bx
seqy将评估x,足以检查它是否为底部,然后丢弃结果并评估y.这可能看起来没什么用,但这意味着在考虑y之前保证会对x进行求值.
这对Haskell来说非常好,但它是否意味着在
x `seq` f x
Run Code Online (Sandbox Code Playgroud)
评估费用x将支付两次("丢弃结果")?
dfl*_*str 18
该seq函数将丢弃该值x,但由于该值已被评估,所有引用x都将"更新",不再指向未x评估的版本,而是指向评估版本.因此,即使seq评估和丢弃x,也已为其他用户评估该值x,导致不重复评估.
ram*_*ion 12
不,它不是计算而忘记,它是计算 - 它强制缓存.
例如,考虑以下代码:
let x = 1 + 1
in x + 1
Run Code Online (Sandbox Code Playgroud)
由于Haskell很懒,所以评估为((1 + 1) + 1).一个thunk,包含thunk和one的总和,内部thunk是一加一.
让我们使用非懒惰语言javascript来展示它的样子:
function(){
var x = function(){ return 1 + 1 };
return x() + 1;
}
Run Code Online (Sandbox Code Playgroud)
像这样链接在一起的thunk可能会导致堆栈溢出,如果反复执行,那么seq救援.
let x = 1 + 1
in x `seq` (x + 1)
Run Code Online (Sandbox Code Playgroud)
当我告诉你这个评价时,我撒谎(2 + 1),但这几乎是正确的 - 只是在剩下的事情发生之前强制发生2的计算(但是仍然懒得计算2).
回到javascript:
function(){
var x = function(){ return 1 + 1 };
return (function(x){
return x + 1;
})( x() );
}
Run Code Online (Sandbox Code Playgroud)