2011-12-25 2 views
10

Я заметил эту идиому в Data.Unique:Насколько безопасен `unsafePerformIO (newTVarIO 0)`?

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

ли это гарантированно работать только один раз?

+0

Как правило, 'unsafePerformIO' следует использовать только как деталь реализации кода библиотеки, а затем вы должны использовать его только потому, что вы совершенно уверен, что нет абсолютно никакого другого способа добиться такой же производительности/поведения. Я не совсем уверен, почему я почувствовал необходимость сказать, что здесь, так как на вопрос не на 100%, но там вы идете. –

+0

Связанные: http://stackoverflow.com/questions/6076129/ – fuz

ответ

11

В GHC, да. Для получения дополнительной информации см. the documentation; существует вариант unsafeDupablePerformIO, который может выполняться несколько раз, что позволяет избежать накладных расходов, связанных с достижением этой гарантии.

Обратите внимание, что unsafePerformIO для создания изменяемых переменных небезопасно вообще; как описано в документации, вы можете создать полиморфную ссылку и использовать ее для реализации unsafeCoerce. Это не то, что вы, скорее всего, сделаете случайно, и это не относится к рассматриваемому коду (так как тип ссылки указан явно).

Пакет safe-globals содержит в себе эту «идиому» (полезную в некоторых случаях, это generally considered an antipattern и ее нельзя использовать в нормальном коде) таким образом, чтобы обеспечить безопасность.

См. Также мой previous answer на unsafePerformIO и предостережение, которое необходимо использовать при его применении.

Я уверен, что это относится ко всем другим реализациям; особая забота GHC, чтобы избежать повторного выполнения, необходима только в поточной настройке, и я не знаю никаких других потоковых реализаций Haskell. GHC является единственной реализацией, которую люди действительно используют в наши дни, хотя ...

Смежные вопросы