Почему я не могу получить доступ к внутренней структуре ORD_SET моей структуры?

Это упражнение, которое я составил, призвано помочь мне понять сигнатуры, структуры и функторы в стандартном машинном обучении. Кажется, я не могу заставить его работать. Для справки я использую

Standard ML of New Jersey v110.75 [built: Sun Jan 20 21:55:21 2013]

У меня есть следующая подпись ML для «объекта, для которого вы можете вычислить величину»:

signature MAG_OBJ =
sig
   type object
   val mag : object -> int
end

Если я хочу дать структуру «наборов int с величиной», я мог бы иметь структуру для упорядоченного int для использования с подписью ORD_SET стандартной библиотеки следующим образом:

structure OrderedInt : ORD_KEY =
struct
   type ord_key = int
   val compare = Int.compare
end

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

functor MakeMagSet(structure ELT : ORD_KEY) : MAG_OBJ =
struct
   structure Set : ORD_SET = RedBlackSetFn(ELT)
   type object = Set.set
   val mag = Set.numItems
end

Пока все хорошо (по крайней мере, все компилируется). Теперь я создаю экземпляр структуры для моей структуры OrderedInt, которую я сделал выше:

structure IntMagSet = MakeMagSet(structure ELT = OrderedInt)

Но когда я пытаюсь его использовать (создать набор и вычислить его величину), я получаю сообщение об ошибке:

val X = IntMagSet.Set.addList(IntMagSet.Set.empty, [0,1,2,3,4,5,6,7,8,9])

выдает ошибку:

Error: unbound structure: Set in path IntMagSet.Set.empty.addList

Насколько я понимаю, приписывание подписи непрозрачно с помощью:> делает так, что нельзя получить доступ к каким-либо внутренним элементам структуры, которые не определены явно в подписи, но я приписал MAG_OBJ прозрачно, поэтому я должен иметь доступ к структуре Set, верно ? Что мне здесь не хватает?

[РЕДАКТИРОВАТЬ]

Даже переписывать функтор для привязки функций, которые я хочу, к структуре бесполезно:

functor MakeMagSet(structure ELT: ORD_KEY) : MAG_OBJ =
struct
   structure Set : ORD_SET = RedBlackSetFn(ELT)
   type object = Set.set
   val mag = Set.numItems
   val empty = Set.empty
   val addList = Set.addList
end

Попытки получить доступ к пустым и addList дают несвязанные переменные ошибки.

С другой стороны, попытка явно определить структуру Set вне структуры и использовать ее функции дает ошибку типа при вызове mag:

Error: operator and operand don't agree [tycon mismatch]
  operator domain: IntMagSet.object
  operand:         Set.set
  in expression:
    IntMagSet.mag X

person JeremyKun    schedule 29.04.2013    source источник
comment
Только что понял, что не могу сказать IntMagSet.Set.empty.addList, потому что я глуп и слишком привык к объектно-ориентированному стилю. Думаю, здесь все еще есть проблема, но мне нужно отредактировать вопрос.   -  person JeremyKun    schedule 29.04.2013


Ответы (1)


Я думаю, это потому, что вы явно сказали, что тип MakeMagSet создает MAG_OBJ, чья подпись не содержит Set. Если вы избавились от : MAG_OBJ или заставили MAG_OBJ включать ORD_SET, то это сработает.

person newacct    schedule 29.04.2013
comment
Нет смысла включать в каждый MAG_OBJ ORD_SET, потому что что, если я хочу вычислить величины для вещей, которые не установлены? - person JeremyKun; 29.04.2013
comment
Кажется, что установка: MAG_OBJ не просто проверяет соответствие полученной структуры интерфейсу, но и ограничивает ее выполнение. Удаление: MAG_OBJ действительно решает проблему. Теперь, если я использую его, например, еще один функтор, я все еще могу поставить: MAG_OBJ и заставить его использовать функцию mag, но тогда я больше не могу ссылаться на базовый набор. Это заставляет меня задаться вопросом, почему приписывание типов в функторе вообще является функцией; это делает мою структуру совершенно бесполезной! - person JeremyKun; 29.04.2013