Беда в том, как вы считаете мощность множества.
Чтобы подсчитать количество элементов множества, вы просматриваете каждый элемент, удаляете его, а также все последующие вхождения того же элемента, увеличивая количество на единицу для каждого такого удаления.
В частности, часть «а также все последующие вхождения того же элемента» - это то, что терпит неудачу.
Тип int
является типом равенства, поэтому в этом случае сравнение двух целых чисел, чтобы увидеть, одинаковы ли они, работает хорошо.
Тип int Set
, однако, не является типом равенства. Это означает, что вызов list_remove
не будет работать, поскольку он не может сравнивать два int Set
s.
Почему это, спросите вы? Ну, рассмотрим следующее:
val onlythree = singleton 3; (* {3} *)
val onlythree_2 = union (onlythree, onlythree); (* {3} U {3} = {3} *)
Оба эти набора представляют один и тот же набор, однако внутренние представления различаются:
onlythree = set [3]
onlythree_2 = set [3, 3]
Итак, если вы позволите стандартному оператору равенства работать непосредственно с ними, вы получите, что они будут другими, даже если они представляют один и тот же набор. Это не хорошо.
Одним из способов исправить это может быть обеспечение того, чтобы множество всегда представлялось его «каноническим представлением» всякий раз, когда вы возвращаете результат из операции над множеством. Однако я не уверен, что это вообще возможно.