2009-03-12 2 views
12

У меня проблема с функтором (и это результирующий тип). Ниже у меня есть функтор Set, который использует упорядоченный тип. Я фактически использовал set.ml, который поставляется с ocaml для некоторых рекомендаций, но я, кажется, все делаю ahhem справа. Я создал упорядоченный модуль с целыми числами и применил его к функтору Set, чтобы получить последний модуль в этом примере кода, IntSet.Функторы в Ocaml

Следующая строка не работает, когда я пытаюсь вставить целое число. Я получаю следующую ошибку типа:

Не поймите меня неправильно, система типов здесь верна. Верхний уровень сообщает, что тип SetInt.elt равен Set(OrdInt).elt, но когда я выполняю те же операции по настройке набора, используя тот, который предоставляется ocaml, «такая же» строка, SetInt.elt = OrderedInt.t. Кажется, я должен получать SetInt.elt = Ordered.t.

Это так просто, я, вероятно, просто пропустил некоторые глупые детали! Argh!

Обращаем ваше внимание, что здесь упрощены функции ввода/вставки, поскольку эта проблема связана с типами.

module type Ordered = 
    sig 
    type t 
    val lt : t -> t -> bool 
    val eq : t -> t -> bool 
    val leq : t -> t -> bool 
    end 

module type S = 
    sig 
    type elt 
    type t 
    exception Already_Exists 
    val empty : t 
    val insert : elt -> t -> t 
    val member : elt -> t -> bool 
    end 

module Set (Elt:Ordered) : S = 
    struct 
    type elt = Elt.t 
    type t = Leaf | Node of t * elt * t 
    exception Already_Exists 
    let empty = Leaf 
    let insert e t = t 
    let member e t = false 
    end 

module OrdInt : Ordered = 
    struct 
    type t = int 
    let lt a b = a < b 
    let eq a b = a = b 
    let leq a b = a <= b 
    end 

module IntSet = Set (OrdInt) 

(* line that fails *) 
let one_elm = IntSet.insert 1 IntSet.empty 

ответ

14

Вы должны изменить эти две строки

module Set (Elt:Ordered) : S = 
module OrdInt : Ordered = 

в

module Set (Elt:Ordered) : S with type elt = Elt.t = 
module OrdInt : Ordered with type t = int = 

Без них, модули не будут иметь подписи, открывающие типы еи и т в междунар.

[Изменить]: У set.ml нет бит «с», потому что есть sml.mli, который объявляет подпись для функтора, и у него есть «с». Кроме того, OrdInt не нужно «с», если вы явно не указать подпись для него, как это:

module OrdInt = 

Вы также можете построить множество, определив модуль на месте:

module IntSet = Set (struct 
type t = int 
let lt a b = a < b 
let eq a b = a = b 
let leq a b = a <= b 
end) 
Смежные вопросы