SML 仿函数在不公开实现的情况下公开类型(实现集)
SML functor expose a type without exposing implementation (implementing sets)
我正在编写一个仿函数来在标准 ML 中实现集合。由于集合不允许重复而且我不希望它被限制为相等类型,它声明如下:
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
,但它增加了不必要的复杂性。
您需要有时称为 半透明 签名归属的东西,也就是说,您隐藏了一些类型并公开了其他类型:
functor ListSet (Eq : EQ) :> SET where type t = Eq.t = ...
您必须使用类型优化公开类型 t
:
functor ListSet (Eq : sig type t val equal : t * t -> bool end) :> SET where type t = Eq.t =
struct
...
end
这等同于签名 SET
的扩展,其中类型 t
被透明地指定为
type t = Eq.t
我正在编写一个仿函数来在标准 ML 中实现集合。由于集合不允许重复而且我不希望它被限制为相等类型,它声明如下:
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
,但它增加了不必要的复杂性。
您需要有时称为 半透明 签名归属的东西,也就是说,您隐藏了一些类型并公开了其他类型:
functor ListSet (Eq : EQ) :> SET where type t = Eq.t = ...
您必须使用类型优化公开类型 t
:
functor ListSet (Eq : sig type t val equal : t * t -> bool end) :> SET where type t = Eq.t =
struct
...
end
这等同于签名 SET
的扩展,其中类型 t
被透明地指定为
type t = Eq.t