2017-07-04 82 views
0

我正在寫一個仿函數來實現標準ML中的集合。由於集合不允許重複,我不希望它被限制在平等類型,它的聲明如下:SML仿函數公開一個類型而不公開實現(實現集)

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 

我用:>,這樣的列表操作不能在臺使用,隱藏了內部實現並允許改變表示(例如到BST)

然而,這還隱藏type t,因此像這樣使用提供了一個錯誤時起作用add

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) 

有一種方法保持隱藏的實現,但以某種方式暴露類型t?還是有更好的方法來實現集?

P.S.我不能擁有平等類型的主要原因是允許套集,並且雖然我可以保持列表排序並定義eqtype 'a set,但它增加了不必要的複雜性。

回答

1

你需要什麼有時被稱爲半透明簽名歸屬,那就是,你隱藏的一些類型和揭露他人:

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

你必須使用一個類型精揭露類型t

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

這等同於其中類型t被透明指定爲

簽名 SET的膨脹
type t = Eq.t