我正在编写一个仿函数来实现标准ML中的集合。由于集合不允许重复,并且我不希望它被限制为相等类型,因此它被声明为:
$ echo "$s" | rev | cut -d. -f1-3 | rev
163data.com.cn
$ echo "$s" | rev | cut -d. -f1-4 | rev
dynamic.163data.com.cn
$ # and easy to use with file input
$ cat ip.txt
98.254.237.114.broad.lyg.js.dynamic.163data.com.cn
foo.bar.123.baz.xyz
a.b.c.d.e.f
$ rev ip.txt | cut -d. -f1-3 | rev
163data.com.cn
123.baz.xyz
d.e.f
我使用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
有没有办法隐藏实现,但不知何故暴露类型t?或者有更好的方法来实现集合吗?
P.S。我不能拥有相等类型的主要原因是允许集合集,虽然我可以对列表进行排序并定义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)
,但它会增加不必要的复杂性。
答案 0 :(得分:1)
你需要有时被称为半透明签名的归属,也就是说,你隐藏了一些类型并暴露了其他类型:
functor ListSet (Eq : EQ) :> SET where type t = Eq.t = ...
答案 1 :(得分:1)
您必须使用类型细化公开类型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