我在Data.Unique中注意到了这个成语:
uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}
是否保证只能运行一次?
最佳答案
在GHC中,为1。有一个可以多次执行的unsafeDupablePerformIO
变体,避免了实现此保证所需的开销。
请注意,使用unsafePerformIO
创建可变变量通常并不安全;如文档中所述,您可以创建一个多态引用,并将其用于实现unsafeCoerce
。但是,这不是您很可能会意外地执行的操作,并且它不适用于所讨论的代码(因为引用的类型是明确指定的)。
the documentation软件包以确保安全的方式抽象了此“惯用语”(在某些情况下很有用,它是safe-globals,不应在常规代码中使用)。
另请参见有关unsafePerformIO
的我的generally considered an antipattern及其应用时必须注意的注意事项。
1我很确定它也适用于所有其他实现; GHC采取的特殊措施以避免重复执行仅在线程设置中才有必要,我不知道Haskell的任何其他线程实现。但是,GHC是当今人们真正使用的唯一实现方式,但是...