J'écris un foncteur pour implémenter des ensembles en ML standard. Étant donné que les ensembles ne permettent pas de doublons et je ne veux pas qu'il soit contraint à des types d'égalité, il est déclaré comme ceci:Le foncteur SML expose un type sans exposer l'implémentation (implémentation des ensembles)
signature SET = sig
type t
type 'a set
val add : t -> t set -> t set
...
end
functor ListSet (EQ : sig type t val equal : t * t -> bool end) :> SET = struct
type t = EQ.t
type 'a set = 'a list
fun add x s = ...
...
end
J'utilise :>
afin que les opérations de liste ne peuvent pas être utilisés sur des ensembles, se cachant la mise en œuvre interne et permettant de changer la représentation (par exemple à un BST)
Cependant, cela cache aussi type t
, fonctionne donc add
lorsqu'il est utilisé comme ceci donne une erreur:
structure IntSet = ListSet (struct type t = int val equal = op= end);
val s0 = IntSet.empty
val s1 = IntSet.add 0 s0
Function: IntSet.add : IntSet.t -> IntSet.t IntSet.set -> IntSet.t IntSet.set
Argument: 0 : int
Reason:
Can't unify int (*In Basis*) with
IntSet.t (*Created from applying functor ListEqSet*)
(Different type constructors)
est-il un moyen pour garder l'implémentation cachée mais en quelque sorte exposer le type t? Ou y a-t-il une meilleure approche pour mettre en place des ensembles?
P.S. La principale raison pour laquelle je ne peux pas avoir de types d'égalité est de permettre des ensembles d'ensembles, et bien que je puisse garder les listes triées et définir eqtype 'a set
, cela ajoute une complexité inutile.