yourself sintaxis learn intercalate functions example haskell types

haskell - sintaxis - La extensión XTypeOperators no funciona como pragma



sintaxis haskell (3)

Estoy usando GHCi 7.0.3 con el siguiente programa que implementa la lista de nivel de tipo:

{-# LANGUAGE TypeOperators #-} data True data False -- List data Nil data Cons x xs -- Type-level infix operator must begin with '':'' data x ::: xs infixr 5 ::: -- set precedence level to 5 (tight)

Se compila, pero cuando lo pruebo con:

:t (undefined :: True:::Nil)

(¿Cuál es el tipo de undefined cuando se emite para escribir True:::Nil ?) Aparece este error:

Illegal operator `:::'' in type `True ::: Nil'' Use -XTypeOperators to allow operators in types

Y de hecho, cuando empiezo GHCi con la bandera

-XTypeOperators

Obtengo el resultado esperado:

(undefined :: True ::: Nil) :: True ::: Nil

Mi pregunta es: ¿Por qué no funciona el pragma equivalente?

{-# LANGUAGE TypeOperators #-}

Editar: Si los pragmas no se extienden al entorno GHCi, tengo otro acertijo. Intenté este programa:

class And b1 b2 b | b1 b2 -> b where andf :: b1 -> b2 -> b -- truth table instance And True True True where andf = undefined instance And True False False where andf = undefined instance And False True False where andf = undefined instance And False False False where andf = undefined

Requería los siguientes pragmas:

{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-}

Pero una vez compilado, podría usarlo en GHCi:

*Main> :t andf (undefined::True) (undefined::False) andf (undefined::True) (undefined::False) :: False

Supongo que en el caso de la lista, el intérprete ni siquiera podía analizar la expresión con el operador de tipo de tipo ::: , mientras que en el caso de las clases de multiparámetros, la línea de comando era analizable. Pero, pensándolo bien, GHCi realizó la inferencia de tipos utilizando clases de parámetros múltiples y dependencias funcionales, ¿no es así? Esta inferencia tipo se hace en GHCi, y no llamando a alguna función en el código compilado, ¿verdad?


El pragma LANGUAGE funciona para el archivo fuente, no se propaga al ghci -prompt. Como es posible tener pragmas conflictivos en múltiples archivos fuente de un proyecto, los pragmas fuente no pueden propagarse por defecto al ghci -prompt. Sería posible tener los pragmas de *module s efectivos en el momento, no estoy seguro, pero creo que se considera implementar eso, de todos modos, hasta ahora, no está implementado, por lo que debe configurar las extensiones para ghci explícitamente.


Las otras respuestas son correctas acerca de habilitar la extensión en GHCi, ya sea desde el indicador de GHCi o como un indicador al iniciar GHCi. Sin embargo, hay una tercera opción: puede crear un archivo .ghci que se cargará y ejecutará cada vez que inicie GHCi, y lo usará para habilitar la extensión automáticamente. Particularmente para cosas como TypeOperators , donde hay muy poco daño en tenerlo habilitado, es muy conveniente.

Por ejemplo, aquí está lo que el mío parece ahora:

:set prompt "∀x. x ⊢ " :set -XTypeOperators import Control.Monad import Control.Applicative import Control.Arrow

El archivo .ghci entra en la ubicación estándar de su sistema para dichos archivos.

Para responder a su pregunta extendida: El código en cuestión funciona en GHCi más o menos porque también funcionaría si se usara en otro módulo, que importó el módulo usando los pragmas pero no los habilitó por sí mismo. GHC es más que capaz de habilitar extensiones por módulo, incluso cuando las definiciones exportadas posiblemente no tengan sentido sin una extensión, o tengan tipos inferidos que lo requieran.

La distinción es un poco confusa en GHCi porque también pone en alcance las definiciones no exportadas del módulo, pero en general cualquier cosa que funcione si se usa desde otro módulo también funcionará en el indicador de GHCi.


Tu pragma es correcto; el problema es que está tratando de usarlo desde dentro de GHCi, que no hereda las extensiones del módulo cargado, 1 sino que pasa las opciones que le dio a GHC para compilar los archivos que lista (razón por la cual tiene el mismo efecto que el pragma).

Debe conservar el pragma y pasar -XTypeOperators cuando inicie GHCi, o habilitarlo después de cargar el archivo de la siguiente manera:

GHCi> :set -XTypeOperators

1 Que podría ser muy indeseable, y probablemente imposible en muchos casos, por ejemplo, cargar módulos compilados.