2012-03-24 11 views
7

¿Hay una manera de conectar una función Haskell del tipoPlug nuevo método FFI en GHC

myFFI :: (C a) => String -> IO a 

(donde C es alguna clase de tipos que describe los tipos de variables que pueden importar) en GHC como un esquema de FFI para que puedo escribir en mis cosas programa Haskell como

foreign import myFFI "foo" foo :: T1 -> T2 

que se compila en una llamada a foo = unsafePerformIO $ myFFI "foo" :: T1 -> T2?

Imagino que esto se puede hacer modificando GHC, pero ¿hay alguna manera de hacerlo a través de un complemento que pueda escribir sin tocar la base de código de GHC?

+0

Parece que los tipos no coinciden. Creo que tendrías '(T1 -> T2)' == 'IO a', y esto no comprueba el tipo. – Tener

+1

@Tener, 'unsafePerformIO' realizará la operación IO (insegura, par), que permitirá que la expresión sea de cualquier tipo' a', en este caso para que 'a ~ (T1 -> T2)'. – dflemstr

+0

Me he dado cuenta de que debería ser fácil obtener algo lo suficientemente bueno usando TH. Así que ahora tengo '[myFFI | Whatever.x :: T1 -> T2 |]' que se compila en 'x = unsafePerformIO $ myFFI" Whatever.x ":: T1 -> T2'. ¿Hay alguna manera de hacer que estos 'insegurosPerformIO's se ejecuten al inicio en lugar de funcionar de forma perezosa? – Cactus

Respuesta

1

Para responder la pregunta en los comentarios (ya que la pregunta principal se responde con "use TH"), también puede usar TH para recopilar una lista de todos los nombres que ha enlazado. Luego, al inicio, una llamada init puede atravesar eso y forzarlos.

0

No es necesario que el segundo argumento esté en la mónada IO en primer lugar.

foreign import ccall sin :: Double -> Double 

es perfectamente legítimo, pero conduce a un comportamiento indefinido si el pecado es impuro.

+0

Creo que estás malinterpretando mi pregunta ... Necesito hacer IO para cargar mi función por nombre. Esa es la parte que me gustaría hacer en el momento de la compilación. Esto es completamente independiente de si la función que cargo (el 'a') es pura o no. – Cactus