2012-07-02 7 views
5

En mi programa Haskell Tengo un ADT con muchos constructores:¿Cómo se determina el constructor de datos a partir del código externo?

data MyData = Con1 | 
    Con2 | 
    ... 
    Con20 

que tienen una función foreign export ccall, que se envuelve en una matriz de [MyData]StablePtr's. Después de llamarlo, necesito determinar qué constructor se ha utilizado para construir cada elemento.

Se podría resolverse de esta manera

foreign export ccall getType :: StablePtr MyData -> IO CInt 
getType (Con1) = return 1 
getType (Con2) = return 2 
... 

pero entonces tendría que definir manualmente estas constantes en la cabecera C. Esto es propenso a errores, así que me pregunto si hay una manera de hacer que GHC haga este trabajo por mí.

Respuesta

0

He encontrado una solución para esto.

he definido como posibles tipos de constructor enum en mi código C:

typedef enum 
{ 
    MyDataCon1, 
    MyDataCon2, 
    ... 
    MyDataCon20 
} MyDataConstructor; 

Luego utiliza C->Haskell gancho de enumeración en mi fuente Haskell:

{#enum MyDataConstructor deriving (Show) #} 

Después de preprocesamiento esta línea se vuelve a

data MyDataConstructor = MyDataCon1 
    | MyDataCon2 
    ... 
    | MyDataCon20 

Ahora puedo definir getType de esta manera:

foreign export ccall getType :: StablePtr MyData -> IO CInt 
getType md = do 
    md' <- deRefStablePtr md 
    case md' of 
     Con1 -> return $ fromEnum MyDataCon1 
     Con2 -> return $ fromEnum MyDataCon2 
     ... 
     Con20 -> return $ fromEnum MyDataCon20 
5

derivando Enum para su tipo de Haskell, y exporta fromEnumMyData :: MyData -> Int ; fromEnumMyData = fromEnum.

Luego puede hacer análisis de casos en el lado C mirando la etiqueta Int que asigna GHC.

+0

Lo sentimos, no lo consiguió. ¿Cómo sé a qué constructor refiere alguna etiqueta? – arrowd

+0

No lo hace, está dado por el orden de enumeración. Pero ya ha perdido toda esa información en el lado C, por lo que debe confiar en un mapeo inseguro. –

+0

Entonces, ¿no es posible generar automáticamente esa asignación? – arrowd

Cuestiones relacionadas