2013-01-31 19 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上的多態性並不存在:你沒有得到任何可以使這個參數變化的函數)。