2017-07-04 5 views
0

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.

Répondre

1

Vous avez besoin ce qui est parfois appelé ascription signature translucide, qui est, vous cacher quelques-uns des types et exposer les autres:

functor ListSet (Eq : EQ) :> SET where type t = Eq.t = ... 
1

Vous devez exposer le type t en utilisant un raffinement de type:

functor ListSet (Eq : sig type t val equal : t * t -> bool end) :> SET where type t = Eq.t = 
struct 
    ... 
end 

Ceci est équivalent à une expansion de la signature SET où le type est spécifié t transparente que

type t = Eq.t