2017-07-04 52 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