我在Data.Unique注意到这个成语:
uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}
保证只运行一次吗?
答案 0 :(得分:11)
在GHC中,是。 1 有关详细信息,请参阅the documentation;有一个变体unsafeDupablePerformIO
可以多次执行,避免了专门用于实现此保证的开销。
注意unsafePerformIO
创建可变变量一般不安全;如文档中所述,您可以创建多态参考并使用它来实现unsafeCoerce
。但是,这不是你可能意外做的事情,并且它不适用于有问题的代码(因为明确指定了引用的类型)。
safe-globals包以确保安全的方式抽象出这个“成语”(虽然在某些情况下有用,但它是generally considered an antipattern,并且不应在正常代码中使用)。
另请参阅unsafePerformIO
上的previous answer以及申请时必须注意的注意事项。
1 我很确定它也适用于所有其他实现; GHC需要特别注意以避免重复执行只在线程设置中,并且我不知道Haskell的任何其他线程实现。 GHC是人们现在真正使用的唯一实现,但是......