2012-04-04 5 views
7

He estado leyendo acerca de unsafePerformIO últimamente, y me gustaría preguntarle algo. Estoy de acuerdo con el hecho de que un lenguaje real debería poder interactuar con el entorno externo, por lo que unsafePerformIO está algo justificado.¿Cómo saber cuándo una interfaz Haskell aparentemente pura esconde operaciones inseguras?

Sin embargo, a mi leal saber y entender, no conozco ninguna forma rápida de saber si una interfaz/biblioteca aparentemente pura (a juzgar por los tipos) es realmente pura sin inspeccionar el código en busca de llamadas al unsafePerformIO (la documentación podría omitir mencionarlo). Sé que debe usarse solo cuando esté seguro de que la transparencia referencial está garantizada, pero me gustaría saber de todos modos.

+3

"Sé que debe usarse solo cuando esté seguro de que la transparencia referencial está garantizada" exactamente. Solo se debe usar cuando las operaciones internas no puedan filtrarse hacia el exterior de cualquier forma razonable, es decir, cuando no haya forma de saber si hay algo de ese tipo que esté sucediendo bajo el capó. – leftaroundabout

+1

Por cierto, el uso de 'unsafePerformIO' para interactuar con el entorno externo es exactamente lo que * no * puedes hacer. Se supone que todos los efectos son internos a su código, como la utilización de una variable mutable detrás de escena para implementar la memorización. – ehird

+0

@ehird: Gracias por la explicación adicional, pero cuando escribí "environment" lo quise decir en el sentido más amplio posible, que también incluye bibliotecas externas (no haskell). No pensé en la interacción del usuario. –

Respuesta

10

No hay forma de verificar el código fuente. Pero eso no es demasiado difícil, ya que Haddock brinda un buen enlace directamente a las definiciones resaltadas por la sintaxis en la documentación. Consulte los enlaces "Fuente" a la derecha de las definiciones en this page para ver un ejemplo.

Safe Haskell es relevante aquí; se usa para compilar código Haskell en situaciones en las que no se permite el uso de la funcionalidad insegura. Si un módulo utiliza un módulo inseguro (como System.IO.Unsafe) y no está marcado específicamente como Trustworthy, heredará su estado inseguro. Pero los módulos que usan unsafePerformIO generalmente lo usarán de manera segura, y por lo tanto se declaran a sí mismos Trustworthy.

+0

Gracias, por lo que es justo como pensaba ... código fuente o nada. Bueno, al menos, aunque garantizado de nuevo por el programador, Safe Haskell puede ayudar a identificar automáticamente algunos módulos inseguros. –

5

En el caso de que esté pensando, el uso de unsafePerformIO no está justificado. El documentation for unsafePerformIO explica esto: solo se aplica a los casos en los que el implementador puede demostrar que no hay forma de romper transparencia referencial, es decir, semántica "puramente funcional". Es decir, si alguien usa unsafePerformIO de una manera que un programa puramente funcional puede detectarlo (por ejemplo, escribir una función cuyo resultado depende de más que solo sus argumentos), entonces ese es un uso no permitido.

Si se encontró con un caso así, la posibilidad más probable es que haya encontrado un error.

+2

De la pregunta: "Sé que debe usarse solo cuando esté seguro de que la transparencia referencial está garantizada, pero me gustaría saber de todos modos". – ehird

+0

@sacundium: Tiene razón, ya vi la página de documentación para 'unsafePerformIO' pero eso es solo una regla, y no estoy seguro de que el programador tenga una prueba de transparencia referencial :) –

Cuestiones relacionadas