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 に答える