2011-11-29 11 views
10

He estado jugando con la creación de un DSEL totalmente tipado en Haskell usando GADTs y tal para un AST completamente seguro, y parece que hacer un compilador correctamente escrito requiere construcciones tales como mapas de tipos Haskell tanto para los tipos como para los valores (entornos tipados) y de manera que el sistema de tipo Haskell pueda entenderlo. C++ tiene la biblioteca Boost.Fusion con construcciones como estas (tipos-> mapas de valores, vectores de valores tipados, etc.). Data.Tuple se encarga de las secuencias, pero ¿hay versiones Haskell de cosas como Boost.Fusion map s?Haskell equivalente a Boost.Fusion

+0

¿Cuál fue el motivo del vencimiento? –

+0

Cuando describes un "compilador" ¿de qué representación estás compilando desde/a? Si tiene el GADT, ¿está realmente escribiendo el intérprete para él o una función del GADT para, por ejemplo, el código C? – sclv

+0

O bien, los mismos problemas aparecerán en cualquier cosa que traduzca el AST tipeado a cualquier otra cosa o lo ejecute. –

Respuesta

10

Mire el paquete dependent-map. No lo he usado yo mismo, pero parece hacer lo que estás pidiendo. Si necesita utilizar realmente la igualdad de tipo (y solo de tipo), es posible que necesite acordar un valor predeterminado o utilizar un TypeRep como clave.

1

¿Está buscando Data.Map, y listas? (por ejemplo, [Int]).

+0

No, ya que los elementos deben tener diferentes tipos, y aquí las claves son tipos. Me gustaría algo que haga un mapeo como '(Int-> 5, Float ->" foo ")' en un valor (no una clase de tipo que proporcione una asignación global). Sé cómo escribirlo a mano (creo), pero me preguntaba si alguien ya lo hizo. –

+1

Pruebe el paquete de mapa dependiente: http://hackage.haskell.org/package/dependent-map –

+0

@NathanHowell: ¿Podría publicar esto como respuesta? Lo verificaré, pero se ve en la documentación como si fuera lo que estoy pidiendo. –

4

En primer lugar, la respuesta con demasiada obvia es que se puede escribir fácilmente un "tipo-> valor del mapa" usando Typeable (parte de la biblioteca de la base):

import Data.Typeable 
import Data.Map 

type TypeMap a = Map TypeRep a 

insertT :: Typeable k => k -> a -> Map k a -> Map k a 
insertT v = insert (typeOf k) 

lookupT :: Typeable k => k -> a -> Map k a -> Map k a 
lookupT v = lookup (typeOf k) 

Ahora puede utilizar un código como insertT (undefined :: Int) 5 para insertar elementos por tipo.

Pero mirando a Fusion, esto realmente no se parece a lo que podrías estar buscando. Parece que te permite construir código trabajando en estructuras de datos arbitrarias? Eso es algo que en Haskell se conoce como programación genérica "Chatarra". Consulte papers o hackage para obtener detalles, pero le permite escribir código que procesa estructuras de datos arbitrarias y selecciona valores de tipos determinados.

Algunas otras cosas que vi de Fusion probablemente podrían emularse utilizando bibliotecas como HList o posiblemente fclabels. Pero es realmente difícil de decir más sin mirar lo que realmente necesita.

+0

Su 'TypeMap' funcionará, pero requiere un' unsafeCervecer' para convencer al compilador de que el tipo del lado derecho coincide con el 'TypeRep' a la izquierda (o' Data.Dynamic'). HList parece interesante también; fclabels se parece más a que proporciona cremalleras.No necesito programación de reflexión/datos genéricos sobre tipos de datos arbitrarios, así que no creo que SYB me ayude. –

+0

Bueno, no estaba seguro de si deseaba que el valor en cuestión tuviera su tipo de índice. Si quieres eso, probablemente deberías usar 'HList' (si conoces las claves de tu mapa estáticamente) o una construcción de mapa similar usando' Dynamic' en los valores para evitar 'unsafeCoerce'. –

3

Como se mencionó anteriormente, dependent-map parece como la mejor opción para el lado mapa de cosas, pero recomiendo buscar en la interfaz de HArrayhlist como una alternativa a hacer malabarismos manualmente tuplas.