2013-01-31 20 views
2

在OCaml中,都在普通地图存在多态函数?即:OCaml的:在地图上的多态函数与通用键

你可以有:f : 'a list -> bool为相当于bool f<T> ([T] x)

你也可以有类似:f : ('k,'v) map -> bool作为相当于bool f<K,V> (Map<K,V> x)

如果是这样,那么类型签名的正确语法是什么,以及如何实现这样一个函数(我问,因为map是一个抽象类型,操作它的唯一方法是使用调用的函数Map.Make对混凝土类型)?

感谢

+0

哪种语言用于等效定义? – didierc

回答

3

这取决于哪种类型的普通地图的使用,你必须让(键的类型和值的类型)两个参数之间的区别。如果使用Map.Make仿函数的默认库,你可以在值的类型一般,但键的类型将是固定的(由仿函数实例化):对于给定的关键模块Key,由module MyMap = Map.Make(Key)生成的地图只有一个参数,'v MyMap.t,所以你可以有f : 'v MyMap.t -> bool

还有其他库提供所谓的“多态”映射,其格式为('k, 'v) pmap,它允许在键和值类型上具有多态性。但是,这通常是以较低的静态保证为代价的:如果要以不保留键上的排序的方式更改'k,则会以编译时无法检测到的方式获得不一致的结果。

当然,你可以实现通过提高Map.Make函子(未测试的代码)任何密钥类型工作的附加功能:

module MyMake(K : Map.OrderedType) = struct 
    include Map.Make(K) 
    (* after the "include", all the functions provided by `Map.Make` 
    are available in the module *) 
    let is_not_empty m = not (is_empty m) 
end 

module MyMap = MyMake(String) 
let foo = MyMap.is_not_empty (...) 

(注:如果你并不需要一个持久化集合(无复制/共享价值/回溯),你不关心最坏情况下的复杂性(没有用暴露否认由用户服务攻击),你也可以使用哈希表,与Hashtbl模块,提供了一个('k, 'v) Hashtbl.t类型。但'k上的多态性并不存在:你没有得到任何可以使这个参数变化的函数)。