真的需要单位的爆炸模式吗?

时间:2015-12-10 11:42:04

标签: haskell lazy-evaluation

在黑客堆栈中,我找到了this

!() <- atomicModifyIORef (eoExeCache eo) $ \m' ->
    (Map.insert name epath m', ())

HLint说:“删除那件事”。但我认为这不是一个错字。有没有理由写!()

1 个答案:

答案 0 :(得分:6)

如果有疑问(而不是匆忙),请咨询specification

表达式

do !() <- foo
   bar

desugars

let ok !() = bar
    ok _   = fail ..
in foo >>= ok

rules for function definition这相当于

let ok = \x -> case x of !() -> bar
                         _   -> fail ...
in foo >>= ok

现在rules for bang patterns位于GHC用户指南中,因为它是非标准的haskell。我们发现我们可以将其重写为

let ok = \x -> x `seq` (case x of () -> bar
                                  _  -> fail ...)
in foo >>= ok

现在seq is defined的论点是⊥与否。所以x是⊥,但是seq的第二个参数,即case x of ...,根据semantics of pattern matching也是⊥。或x不是⊥,seq等于第二个参数。在任何一种情况下,上面的代码都与

相同
let ok = \x -> case x of () -> bar
                         _  -> fail ...
in foo >>= ok

,追溯这些步骤,相当于

do () <- foo
   bar

总之:在do表达式中没有理由这样做。

然而,

之间存在差异
let () = foo
in bar

(永远不会评估foo)和

let !() = foo
in bar

因为let-expressions在semantics for bang patterns中有特殊规定。