11

我在Data.Unique中注意到了这个成语:

uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}

是否保证只运行一次?

4

1 回答 1

11

在 GHC 中,是的。1查看文档了解更多信息;有一个变体unsafeDupablePerformIO可以多次执行,避免了专门用于实现此保证的开销。

请注意,unsafePerformIO创建可变变量通常是不安全的。如文档中所述,您可以创建多态引用并使用它来实现unsafeCoerce. 不过,这不是您可能会意外做的事情,并且它不适用于有问题的代码(因为引用的类型是明确指定的)。

safe-globals包以确保安全的方式抽象了这个“惯用语”(虽然在某些情况下很有用,但它通常被认为是一种反模式,不应在正常代码中使用)。

另请参阅我之前的回答以及unsafePerformIO应用时必须注意的事项。

1我很确定它也适用于所有其他实现;GHC 为避免重复执行而采取的特殊措施仅在线程设置中是必要的,而且我不知道 Haskell 的任何其他线程实现。GHC 是当今人们真正使用的唯一实现,尽管......

于 2011-12-25T19:34:04.057 回答