在黑客入侵时,我发现了这个:
!() <- atomicModifyIORef (eoExeCache eo) $ \m' ->
(Map.insert name epath m', ())
HLint说:"删除那件事".但我认为这不是一个错字.有没有理由写!()
?
如果有疑问(而不是匆忙),请参阅规范.
表达方式
do !() <- foo bar
des to to to
let ok !() = bar ok _ = fail .. in foo >>= ok
根据函数定义的规则,这相当于
let ok = \x -> case x of !() -> bar _ -> fail ... in foo >>= ok
现在爆炸模式的规则在GHC用户指南中,因为它是非标准的haskell.我们发现我们可以将其改写成
let ok = \x -> x `seq` (case x of () -> bar _ -> fail ...) in foo >>= ok
现在seq
的定义是它的论证是⊥与否.所以要么x
是⊥,要么是第二个参数seq
,即case x of ...
根据模式匹配的语义也是⊥ .或者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在爆炸模式的语义上有特殊的规定.