2012-03-24 6 views
7

Gibt es eine Möglichkeit, eine Haskell-Funktion vom Typ SteckerStecker neue FFI Verfahren in GHC

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

(wo C einige typeclass die Typen von Variablen beschreiben, ich importieren kann) in GHC als FFI-Schema, so dass ich kann wie

in meinem Haskell Programm Sachen schreiben
foreign import myFFI "foo" foo :: T1 -> T2 

, die in einem Aufruf von foo = unsafePerformIO $ myFFI "foo" :: T1 -> T2 kompiliert wird?

Ich kann mir vorstellen, dass dies durch Ändern von GHC geschehen könnte, aber gibt es eine Möglichkeit, dies über ein Plugin zu tun, das ich schreiben kann, ohne die GHC-Codebasis zu berühren?

+0

Die Arten scheint nicht zu entsprechen. Ich denke, du hättest '(T1 -> T2)' == 'IO a', und das tippt nicht nach. – Tener

+1

@Tener, 'unsafePerformIO' führt die IO-Operation durch (unsafe, even), die den Ausdruck von einem beliebigen Typ' a' annehmen lässt, in diesem Fall also 'a ~ (T1 -> T2) '. – dflemstr

+0

Ich habe festgestellt, dass es leicht sein sollte, mit TH etwas Gutes zu bekommen. So, jetzt habe ich '[myFFI | Was.x :: T1 -> T2 |]' das kompiliert in 'x = unsafePerformIO $ myFFI" Was.x ":: T1 -> T2'. Gibt es eine Möglichkeit, diese 'unsafePerformIO's beim Start statt langsam laufen zu lassen? – Cactus

Antwort

1

Um die Frage in den Kommentaren zu beantworten (da die Hauptfrage mit "Use TH" beantwortet wird), können Sie TH auch verwenden, um eine Liste aller Namen zu sammeln, die Sie gebunden haben. Dann, beim Start, kann ein init Anruf durchgehen und sie erzwingen.

0

Es gibt keine Anforderung, dass das zweite Argument an erster Stelle in der IO-Monade sein soll.

ist vollkommen legitim, führt aber zu undefiniertem Verhalten, wenn Sünde unrein ist.

+0

Ich glaube, du verstehst meine Frage falsch ... Ich muss IO machen, um meine Funktion mit Namen zu laden. Das ist der Teil, den ich zur Kompilierzeit machen möchte. Dies ist völlig unabhängig davon, ob die Funktion, die ich lade (das "a"), rein ist oder nicht. – Cactus