2017-07-11 2 views
0

Ich spiele mit Grund, und ich wollte versuchen, das FFI für debug zu tun, um zu lernen. Ich habe diesen CodeWie bindet man ein ganzes Modul als Funktion?

module Instance = { 
    type t; 
    external t : t = "" [@@bs.module]; 
}; 

module Debug = { 
    type t; 
    external createDebug : string => Instance.t = "debug" [@@bs.module]; 
}; 

und ich versuche es wie diese

open Debug;  
let instance = Debug.createDebug "app"; 
instance "Hello World !!!"; 

zu verwenden, aber ich bekomme die folgenden Fehler

Error: This expression has type Debug.Instance.t 
     This is not a function; it cannot be applied. 

Waren instance binden, um nicht soll eine Funktion? Ich habe auch versucht mit

module Instance = { 
    type t; 
    external write : string => unit = "" [@@bs.send]; 
}; 

und

open Debug;  
let instance = Debug.createDebug "app";  
instance.write "Hello World !!!"; 

aber ich bekomme

Error: Unbound record field write 

Was bin ich?

+1

'Instance.t' ist eine abstrakte Art definiert im Modul' Instance'. Es ist keine Art von Modul. Wenn Sie wirklich Module als Werte behandeln wollen, müssen Sie erstklassige Module verwenden (http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc81). – camlspotter

Antwort

1

Die createDebug-Funktion gibt gemäß Ihrer Deklaration einen Wert vom Typ Instance.t zurück. Es ist ein abstrakter Wert, in einem Sinne, dass nichts über seine Implementierung bekannt ist, und Sie können es nur über seine Schnittstelle verwenden. Die Schnittstelle eines Typs ist im Grunde genommen alle Werte (Funktionen), mit denen Sie einen Wert dieses Typs bearbeiten können. In Ihrem Fall können wir nur zwei solche Werte finden - den Instance.t Wert und Debug.createDebug Funktion. Beide können gemäß Ihren eigenen Erklärungen verwendet werden, um einen solchen Wert zu schaffen. Es sind keine Funktionen verfügbar, um es zu benutzen.

Wahrscheinlich haben Sie einige Missverständnisse darüber, welches Modul ist. Es ist kein Objekt an sich, sondern ein Namensraum. Es ist wie eine Datei in einer Datei.

Ihr zweites Beispiel rechtfertigt, dass Sie an Module denken, da sie eine Art von Laufzeitobjekten oder Datensätzen darstellen. Sie sind jedoch nur statische Strukturen, mit denen große Programme in hierarchischen Namespaces organisiert werden.

Was Sie versuchen, zu verwenden ist eigentlich ein Rekord:

type debug = { write : string => unit } 

let create_debug service => { 
    write: fun msg => print_endline (service^": "^msg) 
} 

let debug = create_debug "server" 
debug.write "started" 

nachgeben:

server: started 
+0

Danke. Aber wenn ich im Instanz-Modul ein Externes wie das externe schreiben: string => unit = "" [@@ bs.send]; 'definiere, warum kann ich' .write' nicht aufrufen? – ThomasThiebaud

+0

weil 'createDebug' keine Instanz eines Moduls erzeugt (in Reason gibt es das nicht), erzeugt es eine Instanz vom Typ' t' und die Funktion 'write' hat nichts mit dem Typ' t' zu tun. Es funktioniert mit Strings nicht mit 't'. Ich habe meine Antwort mit einem Beispiel aktualisiert, das dich in die richtige Richtung bringt :) – ivg

+0

Vielen Dank, ich denke, ich verstehe es. Ich werde mehr darüber lesen – ThomasThiebaud

Verwandte Themen