me he dado cuenta de este idioma en Data.Unique:¿Qué tan seguro es `UnsafePerformIO (newTVarIO 0)`?
uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}
¿Está garantizada sólo a ejecutar una vez?
me he dado cuenta de este idioma en Data.Unique:¿Qué tan seguro es `UnsafePerformIO (newTVarIO 0)`?
uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}
¿Está garantizada sólo a ejecutar una vez?
En GHC, sí. Consulte the documentation para obtener más información; Existe una variante unsafeDupablePerformIO
que se puede ejecutar varias veces para evitar la sobrecarga dedicada a lograr esta garantía.
Tenga en cuenta que unsafePerformIO
para crear variables variables no es seguro en general; como se describe en la documentación, puede crear una referencia polimórfica y usarla para implementar unsafeCoerce
. Sin embargo, eso no es algo que pueda hacer accidentalmente, y no se aplica al código en cuestión (ya que el tipo de referencia se especifica explícitamente).
El paquete safe-globals abstrae esta "expresión idiomática" (aunque es útil en algunos casos, es generally considered an antipattern, y no debe usarse en el código normal) de forma que se garantice la seguridad.
Vea también mi previous answer en unsafePerformIO
y la precaución que debe usarse al aplicarlo.
Estoy bastante seguro de que se aplica a todas las demás implementaciones, también; el cuidado especial que GHC toma para evitar la ejecución repetida solo es necesario en una configuración enhebrada, y no conozco ninguna otra implementación de Haskell. Sin embargo, GHC es la única implementación que las personas realmente usan en la actualidad ...
Como regla general, 'unsafePerformIO' solo debe usarse como un detalle de implementación del código de la biblioteca, y entonces solo debe usarlo porque está bastante seguro de que no hay absolutamente ninguna otra manera de lograr el mismo rendimiento/comportamiento. No estoy del todo seguro de por qué sentí la necesidad de decirlo aquí, ya que no es 100% pertinente a la pregunta, pero ahí lo tienes. –
Relacionados: http://stackoverflow.com/questions/6076129/ – fuz