Я хочу использовать модуль Stack из Stdlib OCaml, но мне также нужна функция принадлежности, которой нет в модуле Stack. Итак, после https://dev.realworldocaml.org/files-modules-and-programs.html я создал файл stack1.ml
, читающий:
include Stack
let mem a t = List.mem a t.c
поскольку c
— это имя записи, используемой в stack.ml
(этот файл содержит строку: type 'a t = { mutable c : 'a list; mutable len : int; }
). Но я получаю:
Error: Unbound record field c
Что я могу сделать ?
(И еще: нужен ли мне файл с другим именем Stack1
? Это немного раздражает вызывающие его файлы.)
Тот факт, что тип 'a Stack.t
реализован с использованием изменяемого списка или любого другого типа данных, является деталью реализации, которая абстрагируется интерфейсом модуля Stack
.
Другими словами, вне модуля Stack
вы можете использовать только функции, предоставляемые модулем стека, который работает с абстрактным типом 'a Stack.t
независимо от этой реализации.
К счастью, этих функций более чем достаточно для реализации функции mem
. Например, с fold
:
let mem x s = Stack.fold (fun acc y -> acc || x = y) false s
Потери эффективности нет.
Потери эффективности нет, но использование стека для проверки членства по своей сути неэффективно. Если производительность членства критична в вашем приложении, вы должны либо использовать лучшую структуру данных (возможно, treap), либо использовать стек (для операций со стеком) в сочетании с набором (для тестирования членства).
Спасибо. Похоже, что
Stack.fold
действительно позволяет делать все, что можно было бы сделать, обратившись к приватному полю. Но есть ли потеря эффективности? (Похоже, что нет, так как в обоих случаях вы перебираете список, но я не уверен, что нет скрытых затрат.)