2015-12-24 3 views
1

Я пытаюсь реализовать Trie, который является общим по типам его ключей и значений, используя Map.Make. Этот функтор принимает Map.OrderedType и создает модуль с кучей утилит Map, определенных внутри него. Однако тип возвращаемого модуля Map.Make является анонимным. Я хочу показать конкретную реализацию карты, которую мой Trie использует под капотом в моем модуле TrieType.Подмодули OCaml с анонимными сигнатурами в типах модулей

Есть ли способ обратиться к типу возвращаемого модуля Map.Make? В качестве альтернативы можно ли использовать что-то похожее на прозрачную заявку в SML, чтобы разоблачить модуль M, не настаивая на конкретном типе модуля для него или не скрывая ни одного из его членов?

module OrderedStringType : Map.OrderedType = struct 
    type t = string 
    let compare = String.compare 
end 

module type TrieType = sig 

    (* I want to expose the M submodule in the interface, but its 
    * module type is anonymous *) 
    (* here is some strawman syntax *) 
    (* module M : Map.Make(Set.OrderedType) *) 
    type 'a t 
end 

module Trie(X : Map.OrderedType) : TrieType = struct 
    module M = Map.Make(X) 

    type 'a t = EmptyTrie | Trie of 'a tChild 
    and 'a tChild = {value : 'a option ; children : 'a t M.t} 
end 


module TruncatedTrie(X : TrieType) = struct 
    (* Implementation to follow *) 
end 
+0

Ваш примерный код очень трудно понять. В комментариях упоминается подмодуль Key, который отсутствует в коде. Модуль OrderedStringType не используется в коде. (Кроме того, вам не нужно писать собственную функцию сравнения. Существует функция 'String.compare'. Операторы' <' and '> 'не менее полиморфны, чем полиморфная функция' compare'.) OCaml имеет конструкцию типа модуля ... что может делать то, что вы хотите, но я не могу сказать. –

+0

Прошу прощения. Я должен был очистить это лучше, прежде чем публиковать его, я постараюсь сделать это более ясным. То, что мне нужно, это способ обращения к подписи, которая возникает, когда «Map.Make» применяется к модулю, удовлетворяющему «Map.OrderedType». Похоже, что использовать 'module type' я мог бы восстановить его с помощью конкретного экземпляра' Map.OrderedType' ... –

+1

Почему бы просто не использовать Map.S? – Drup

ответ

1

Тип модуля, создаваемого Map.Make функтора не является анонимным, но на самом деле есть имя: Map.S. Вы можете расширить или даже скрыть поля с подписью:

module type Trie = sig 
    include Map.S 
    val new_method : t -> int 
end 

Чтобы скрыть метод, вы можете переопределить его с какой-то необитаемый типа:

module type Trie = sig 
    include Map.S 
    val length : [> `trie_doesn't_have_length_method ] 
end 

Последнюю можно рассматривать как хак, так как много более чистым подходом было бы определение вашей собственной подписи.

Смежные вопросы