2014-02-04 4 views
1

я следующий код в OCaml, который производит ошибку «Освобожденный конструктор типа переменной»:OCaml: модуль, класс и тип

module OrderedVar = struct 
type t = variable 
let compare v1 v2 = v1#get_name - v2#get_name 
end 

module VarSet = Set.Make(OrderedVar) 

class variable n = 
object 
    val mutable name = n 

    method get_name = name 
end 

Как я могу объявить тип «переменной»?

Спасибо


редактировать:

поблагодарить вас за ваши ответы, но мой Probleme немного сложнее. На самом деле, у меня есть два модуля и два класса, которые «переплетаются». Здесь я не могу объявить классы «переменные» и «пункта» до модулей, так как они нужны модули:

module OrderedVar = struct 
type t = variable 
let compare v1 v2 = v1#get_name - v2#get_name 
end 

module VarSet = Set.Make(OrderedVar) 

module OrderedClause = struct 
    type t = clause 
    let compare = compare 
end 

module ClauseSet = Set.Make(OrderedClause) 

class variable n = 
object 
    val mutable name = n 
    val mutable cpos = ClauseSet.empty 
    method get_name = name 
end 

class clause = 
object 
    val mutable vpos = VarSet.empty 
end 
+1

Документация по рекурсивным модулям должна помочь вам определить, как правильно их реализовать. http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc75 Хотя вы можете захотеть переосмыслить дизайн, чтобы попытаться избежать этого, если это возможно. Этот пример может быть немного более легким. https://ocaml.janestreet.com/?q=node/84 Важно, чтобы вы использовали и ключевое слово, чтобы объявить два модуля в одном объявлении. – Calvin

ответ

0

Два комментария:

  1. В основном это просто проблема упорядочения ,

  2. Оператор - применяется к ints, поэтому я предполагаю, что ваши имена являются ints?

Следующие компилирует для меня:

class variable n = 
    object 
    val mutable name: int = n 
    method get_name = name 
    end 

module OrderedVar = struct 
    type t = variable 
    let compare v1 v2 = v1#get_name - v2#get_name 
end 

module VarSet = Set.Make(OrderedVar) 

Update

Для нового кода, проще всего разорвать порочный круг (как мне кажется) это с классом variable , Его видимый тип довольно прост. Следующие компиляции для меня:

type variabletype = < get_name : int > 

module OrderedVar = struct 
type t = variabletype 
let compare v1 v2 = v1#get_name - v2#get_name 
end 

module VarSet = Set.Make(OrderedVar) 

class clause = 
object 
    val mutable vpos = VarSet.empty 
end 

module OrderedClause = struct 
    type t = clause 
    let compare = compare 
end 

module ClauseSet = Set.Make(OrderedClause) 

class variable n = 
object 
    val mutable name: int = n 
    val mutable cpos = ClauseSet.empty 
    method get_name = name 
end 

Возможно, это обобщит ОК для вашей реальной проблемы.

+0

Я слишком упростил свой код. Я добавил новый код в свой первый пост, и я думаю, что не могу применить к нему ваше решение. – user3272611

+0

Правда, у вас есть циклическая зависимость. Вы можете определить взаимно рекурсивные модули, а модули могут содержать классы. Но синтаксис будет очень тяжелым. –

+1

Как я могу сделать два модуля взаимно рекурсивно? могу ли я использовать «и» (что мы используем для взаимно рекурсивных функций)? – user3272611

0

Объявите класс переменной, прежде чем использовать его. Заказ важен в Ocaml, в отличие от типичных языков OO на языке C, где классы и методы могут отображаться в любом месте файлов.

Эта цитата из https://realworldocaml.org/v1/en/html/files-modules-and-programs.html

В отличии от C, программа в OCaml не имеет уникальную основную функцию. Когда оценивается программа OCaml, все утверждения в файлах реализации оцениваются в том порядке, в котором они были связаны друг с другом.

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