在黑客堆栈中,我找到了this:
!() <- atomicModifyIORef (eoExeCache eo) $ \m' ->
(Map.insert name epath m', ())
HLint说:“删除那件事”。但我认为这不是一个错字。有没有理由写!()
?
答案 0 :(得分:6)
如果有疑问(而不是匆忙),请咨询specification。
表达式
do !() <- foo
bar
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中有特殊规定。