2011-12-18 2 views
7

Я переключаюсь с Haskell на OCaml, но у меня возникают некоторые проблемы. Например, мне нужно определение типа для регулярных выражений. Я делаю это с:OCaml: круговость между вариантом варианта и определением модуля

type re = EmptySet 
    | EmptyWord 
    | Symb of char 
    | Star of re 
    | Conc of re list 
    | Or of (RegExpSet.t * bool) ;; 

Элементы внутри или находятся в наборе (RegExpSet), поэтому я определяю его в следующий (а также функцию карты):

module RegExpOrder : Set.OrderedType = 
    struct 
     let compare = Pervasives.compare 
     type t = re 
    end 
module RegExpSet = Set.Make(RegExpOrder)  
module RegExpMap = Map.Make(RegExpOrder) 

Однако, когда я «OCaml [имя файла]» Я получаю:

Error: Unbound module RegExpSet 

в строке «Или» в определении «повторно».

Если я поменять эти определения, то есть, если я пишу определения модулей до определения типа повторно я, очевидно, получим:

Error: Unbound type constructor re 

в строке «тип т = ре».

Как я могу это решить? Спасибо!

ответ

9

Вы можете использовать recursive modules. Например, следующие компиляции:

module rec M : 
sig type re = EmptySet 
    | EmptyWord 
    | Symb of char 
    | Star of re 
    | Conc of re list 
    | Or of (RegExpSet.t * bool) 
end = 
struct 
    type re = EmptySet 
    | EmptyWord 
    | Symb of char 
    | Star of re 
    | Conc of re list 
    | Or of (RegExpSet.t * bool) ;; 
end 

and RegExpOrder : Set.OrderedType = 
    struct 
     let compare = Pervasives.compare 
     type t = M.re 
    end 
and RegExpSet : (Set.S with type elt = M.re) = Set.Make(RegExpOrder) 
+0

Спасибо, что ответили! Я добавил это определение в начало моего файла. Однако теперь у меня есть новая проблема, которая возникает, когда я пытаюсь выполнить сопоставление разбиений аргументов функции с элементами типа M.re. Например, эта функция let lf exp = соответствует exp с \t M.EmptyWord -> M.EmptySet ;; дает мне Ошибка: Unbound конструктор M.EmptyWord Рикардо Алмейда – vegetus

+0

об осуществлении типа 're' был сделан абстрактно. Попробуйте удалить подпись модуля 'sig type re end'. Также посмотрите на «частные» типы, которые позволят промежуточный уровень скрытия; вне модуля вам придется использовать специальные конструкторы для получения значений типа 're', но вы все равно можете сопоставлять шаблоны. –

+0

@ user1104586 Я обновил свой ответ, чтобы сделать конструкторы 'M.re' видимыми. –

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

  • Нет связанных вопросов^_^