2010-08-05 10 views
8

Sto sviluppando alcuni algoritmi in OCaml che richiedono alcune parti da "innestare" in modo che parte del calcolo sia lasciata a specifici computatori.Utilizzo di funtori come interfacce in OCaml

solo per fare un esempio supponiamo di avere una firma come questo:

module type Algorithm = sig 
    val feed : float -> unit 
    val nth : int -> (float -> float) 
end 

E due diverse implementazioni che saranno Alg1 e Alg2. Questo modulo Algorithm dovrebbe rappresentare l'interfaccia per varie implementazioni come queste due.

Ora ho bisogno di un altro componente, chiamiamolo Executor che sarà il modulo che utilizza Alg1 o Alg2 throught la loro interfaccia ..

Leggendo funtori sembra che avrei bisogno di un funtore che prende un Algorithm e produce a ConcreteExecutor con un'implementazione specifica dell'algoritmo di cui ho bisogno. In modo che Executor è una sorta di modulo parametrizzato su uno dei suoi componenti ..

Ho ragione? È il modo migliore per ottenere ciò di cui ho bisogno? Mi chiedo thinkgs come questi perché provengo da uno sfondo Java/C++, quindi sono abituato a utilizzare interfacce e classi astratte e ho bisogno di entrare in questo problema di astrazione del modulo/modulo nel modo corretto.

Qual è la sintassi corretta per ottenere ciò che voglio?

Grazie in anticipo

+2

Questo è davvero un grande uso di funtori. Li uso in un'applicazione di generazione di labirinti. Collega un algoritmo e una rappresentazione a labirinto e sei fuori. Sto ancora lavorando all'output che potrebbe essere un altro functor per supportare SVG, GraphViz, PDF e PNG. – nlucaroni

+1

@nlucaroni - il codice per l'applicazione di generazione del labirinto è disponibile ovunque? – aneccodeal

risposta

4

Yup, suona come funtori sono ciò che si desidera. In effetti, puoi dare un'occhiata a come la libreria standard usa i funtori come il codice sorgente è disponibile. Sulla mia macchina si trova in /usr/lib/ocaml/3.10.2/. A titolo di esempio, set.mli contiene quanto segue:

module type OrderedType = 
    sig 
    type t 
    val compare : t -> t -> int 
    end 

module type S 
    sig 
    ... 
    end 

module Make (Ord : OrderedType) : S with type elt = Ord.t 

Quando si desidera utilizzare un set in OCaml che fai:

module SSet = Set.Make(String);; 

Quindi, con il codice, algoritmo sostituisce OrderedType, Alg1/ALG2 sostituisce String, Executor sostituisce Make e ConcreteExecutor è il risultato di Executor (Alg1/Alg2). Noterai inoltre che string.mli/ml non contiene alcuna menzione di OrderedType. String è un OrderedType in virtù del fatto che ha un tipo t che viene utilizzato da una funzione compare. Non è necessario dire esplicitamente che String è un OrderedType.

+0

È necessario aggiornare ocaml. :) – nlucaroni

+0

Ha! Questa è la versione su un computer a cui non ho accesso come root. La mia macchina domestica è più aggiornata (anche se chissà quando Debian avrà 3.12?). –

+0

Potrebbe volerci del tempo, ma sai che la mancanza di compatibilità tra le versioni di OCaml è la colpa dei ritardi, giusto? I "manutentori OCaml" di Debian devono assicurarsi che tutti i pacchetti OCaml in Debian compilino con la nuova versione e li cambino tutti in una volta. Stanno facendo un ottimo lavoro e non è colpa loro. –