haskell - pagina - ¿Hay una lista de extensiones de GHC que se consideran ''seguras''?
haskell pagina oficial (1)
Ocasionalmente, una parte del código que deseo escribir no es legal sin al menos una extensión de idioma. Esto es particularmente cierto cuando se trata de implementar ideas en documentos de investigación, que tienden a usar cualquier versión superrápida y amplia de GHC disponible en el momento en que se escribió el artículo, sin dejar en claro qué extensiones son realmente necesarias.
El resultado es que a menudo termino con algo así en la parte superior de mis archivos .hs:
{-# LANGUAGE TypeFamilies
, MultiParamTypeClasses
, FunctionalDependencies
, FlexibleContexts
, FlexibleInstances
, UndecidableInstances
, OverlappingInstances #-}
No me importa eso, pero a menudo siento que estoy haciendo sacrificios a ciegas para apaciguar al Gran Dios de GHC. Se queja de que un determinado fragmento de código no es válido sin la extensión de lenguaje X, así que agrego un pragma para X. Luego exige que active Y, así que agrego un pragma para Y. Para cuando esto termine, he habilitar tres o cuatro extensiones de idioma que realmente no entiendo, y no tengo idea de cuáles son ''seguras''.
Para explicar lo que quiero decir con ''seguro'':
Entiendo que
UndecidableInstances
es seguro, porque aunque puede causar que el compilador no finalice, siempre que el código se compile no tendrá efectos secundarios inesperados.Por otro lado,
OverlappingInstances
es claramente inseguro, porque me facilita la escritura accidental de código que da errores de tiempo de ejecución.
Entonces mi pregunta es:
¿Hay una lista de GHCextensions que se consideran "seguras" y que son "inseguras"?
Probablemente sea mejor mirar lo que SafeHaskell permite:
Lenguaje seguro
El lenguaje seguro (habilitado a través de
-XSafe
) restringe las cosas de dos maneras diferentes:
- Ciertas extensiones de GHC LANGUAGE no se permiten por completo.
- Ciertas extensiones de GHC LANGUAGE tienen una funcionalidad restringida.
A continuación se detalla qué banderas y extensiones corresponden a cada categoría:
- No permitido por completo:
GeneralizedNewtypeDeriving
,TemplateHaskell
- Funcionalidad restringida:
OverlappingInstances
,ForeignFunctionInterface
,RULES
,Data.Typeable
- Ver las funciones restringidas a continuación
- No importa: todas las banderas restantes.
Funciones GHC Haskell restringidas e inhabilitadas
En el dialecto de lenguaje seguro, restringimos las siguientes características del lenguaje Haskell:
ForeignFunctionInterface
: Esto es principalmente seguro, pero las declaraciones de importación extranjeras que importan una función con un tipo no IO no se permitirán. Todas las importaciones de FFI deben residir en IO Monad.RULES
: Como pueden cambiar el comportamiento del código confiable de formas no anticipadas, violando la consistencia semántica tienen un funcionamiento restringido. Específicamente, cualquierRULES
definida en un móduloM
compilado con-XSafe
se descarta.RULES
definidas en módulos confiables que las importaciones deM
siguen siendo válidas y se activarán como siempre.OverlappingInstances
: esta extensión puede utilizarse para violar la coherencia semántica, ya que el código malicioso podría redefinir una instancia de tipo (al contener una definición de instancia más específica) de forma que cambie el comportamiento del código que importa el módulo que no es de confianza. La extensión no está deshabilitada para un móduloM
compilado con-XSafe
pero restringido. Mientras queM
puede definir declaraciones de instancia superpuestas, solo pueden usarse enM
Si en un móduloN
que importaM
, en un sitio de llamada que utiliza una función de clase de tipo hay una opción de qué instancia utilizar (es decir, superposición) y la opción más específica es deM
(o cualquier otro módulo Compilado de seguridad), entonces la compilación fallará Es irrelevante si el móduloN
se considera Seguro, o Confiable o ninguno de los dos.Data.Typeable
:Data.Typeable
que se deriven instancias deData.Typeable
pero no permitimos instancias hechas a mano. Las instancias derivadas son generadas por máquina por GHC y deben ser perfectamente seguras, pero las creadas a mano pueden mentir sobre su tipo y permitir coerciones inseguras entre los tipos. Esto está en el espíritu del diseño original de SYB.En el dialecto de idioma seguro desactivamos por completo las siguientes características del lenguaje Haskell:
GeneralizedNewtypeDeriving
: se puede usar para violar el control de acceso del constructor, al permitir que el código que no es de confianza manipule los tipos de datos protegidos en formas que el autor del tipo de datos no pretendía. Es decir, puede usarse para romper invariantes de estructuras de datos.TemplateHaskell
: es particularmente peligroso, ya que puede causar efectos secundarios incluso en el momento de la compilación y se puede utilizar para acceder a tipos de datos abstractos. Es muy fácil romper los límites del módulo con TH.
Recuerdo haber leído que la interacción de FunctionalDependencies
y UndecidableInstances
también puede ser insegura, porque más allá de permitir una profundidad ilimitada de la pila de contexto UndecidableInstances
también levanta la llamada condición de cobertura (sección 7.6.3.2), pero no puedo encontrar una cita para esto En el momento.
EDITAR 2015-10-27: Desde que GHC obtuvo soporte para funciones de tipo, GeneralizedNewtypeDeriving
ya no es inseguro. (No estoy seguro de qué más podría haber cambiado).