seqfunction和严格性
我一直在想这个,但是我一直没有find任何关于它的事情。
当使用seq函数时,它是如何真正起作用的? 在任何地方,只是解释说seq ab评估a ,丢弃结果并返回b 。 
但是这到底意味着什么呢? 以下会导致严格的评估:
 foo st = seq q (bar qt) where q = s*t 
 我的意思是,在使用bar之前是否严格评估? 以下是相同的: 
 foo st = seq (s*t) (bar (s*t) t) 
我觉得这个function的function有点难。
 你不是一个人。  seq可能是最难的Haskell函数之一,正确使用,有几个不同的原因。 在你的第一个例子中: 
 foo st = seq q (bar qt) where q = s*t 
  q是在评估bar qt之前评估的。 如果bar qt从来没有评估, q也不会。 所以,如果你有 
 main = do let val = foo 10 20 return () 
 因为从不使用val ,所以不会被评估。 所以q也不会被评估。 如果你有 
 main = print (foo 10 20) 
  foo 10 20的结果被评估(通过print ),因此在foo内q被评估在bar的结果之前。 
这也是为什么这不起作用:
 myseq x = seq xx 
 在语义上,这意味着第一个x将在评估第二个x之前被评估。 但是,如果第二个x从来没有被评估过,那么第一个x也不需要。 所以seq xx和x完全等价。 
 你的第二个例子可能是也可能不是一回事。 在这里,expression式s*t将在bar的输出之前被评估,但是它可能与s*t一个参数不同。 如果编译器执行通用的子expression式消除,则可能会共同使用两个相同的expression式。  GHC对CSE的位置可以相当保守,所以你不能依赖这个。 如果我定义bar qt = q*t它会在bar中使用该值之前执行CSE并评估s*t 。 对于更复杂的expression可能不这样做。 
 你可能也想知道严格的评估是什么意思。  seq将第一个参数评估为弱头标准forms(WHNF),对于数据types来说,这意味着解压最外层的构造函数。 考虑一下: 
 baz xs y = seq xs (map (*y) xs) 
 因为map , xs必须是一个列表。 当seq评估它时,它本质上将代码转换成 
 case xs of [] -> map (*y) xs (_:_) -> map (*y) xs 
这意味着它将确定列表是否为空,然后返回第二个参数。 请注意, 没有任何列表值被评估 。 所以你可以这样做:
 Prelude> seq [undefined] 4 4 
但不是这个
 Prelude> seq undefined 5 *** Exception: Prelude.undefined 
 无论你使用什么样的数据types作为seq第一个参数,对WHNF的评估将足够远以找出构造函数,而不是进一步。 除非数据types的组件被标记为严格的爆炸模式。 那么所有严格的领域也将被评估为WHNF。 
编辑:(感谢丹尼尔·瓦格纳在评论中的build议)
 对于函数, seq将评估expression式,直到函数“有lambda显示”,这意味着它已经准备好了应用程序。 以下是一些可能certificate这意味着什么的例子: 
 -- ok, lambda is outermost Prelude> seq (\x -> undefined) 'a' 'a' -- not ok. Because of the inner seq, `undefined` must be evaluated before -- the lambda is showing Prelude> seq (seq undefined (\x -> x)) 'b' *** Exception: Prelude.undefined 
 如果你认为lambda绑定是一个(内置的)数据构造函数, seq的函数与数据上的使用完全一致。 
此外,“lambda绑定”包含所有types的函数定义,不pipe是由lambda表示法定义还是作为普通函数定义。
  HaskellWiki seq页面的Controversy部分对于seq在function方面的一些后果略有介绍。 
 你可以把seq想成是: 
 seq ab = case a of _ -> b 
 这将评估a头正常forms(WHNF),然后继续评估b 。 
  在8月份的评论之后进行编辑:这种case ... of是严格的,GHC核心的 ,总是强制它的论点。