Функторы, модули и подмодули Ocaml

Прошу прощения за публикацию такого длинного, не компилируемого кода. Но, несмотря на то, что я прочитал несколько вопросов и ответов о stackoverflow на функторах ocaml, я не понимаю, как решить эту проблему:

Предположим, у меня есть очень абстрактная структура данных:

ads.mli

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

module type T = sig
    type entry
    type t
    val create : unit -> t
    val insert : entry -> t -> t
    val delete : entry -> t -> t
end

На основе этого я могу создать конкретные структуры данных в этой абстрактной реализации, передав функтор. e Я сделал:

crete_ads.mli

module Make (Entry: Ads.ENTRY) : (ads.T with type entry = Entry.t)

Эту работу я теперь могу использовать в других исходных файлах, например, вот так:

module AT = Concrete_ads.Make( 
    type t = int * int;; 
    let get_index = fst;; 
    let to_string = (fun (x,y) -> Printf "%i, %i" x y);; 
end);;

А затем использовать реализацию вроде:

let at = AT.create () in
let ati = AT.insert (1,2) at in
let atd = AT.delete (1,2) ati in

.. ... и т. д.

Теперь я хочу написать несколько функций, которые работают с этими структурами данных в отдельном исходном файле, и они должны быть доступны извне. Но я не знаю, как объявить тип этих функций. Примерно так:

search.mli

val search : Int -> Ads.T -> int list

Но при компиляции я получаю:

 Failure: "invalid long identifier type"

Тогда я подумал, что мне нужно специально объявить модуль adt как подмодуль в search.mli , что-то вроде:

search.mli

module AD = Ads;;
 ...
val search : Int -> AD.T -> int list

Но я получаю:

Parse error: [module_declaration] expected after [a_UIDENT] (in [sig_item])

Что мне здесь не хватает? Я чувствую, что либо ошибаюсь с синтаксисом, либо не полностью понимаю концепцию функторов, модулей и подмодулей ...

Edit Большое спасибо за ваше объяснение, гаш! На вашем примере я смог написать то, что хотел. Я отправлю его здесь для пояснения, поскольку, похоже, существует большая путаница с функторами в ocaml.

На самом деле я хотел сделать функцию абстрактной относительно Ads.T ,но требуется определенный тип для Ads.T.t .

Теперь у меня есть search.mli :

module Make (T : Ads.T with type entry = int * int) : sig
    val search : T.t -> int -> int
end;;

И в search.ml :

module Make (T : Ads.T with type entry = int * int) : sig
    val search : T.t -> int -> int 
end = struct
    (* actual implementation of search *)
end;;

И он работал именно так, как я предполагал.

5
задан perror 10 August 2015 в 22:50
поделиться