2012-10-15 70 views
6

我已經爲格式能夠集合算符,具體如下:擴展OCaml的地圖來formattable地圖

module type POrderedType = 
    sig 
    type t 
    val compare : t -> t -> int 
    val format : Format.formatter -> t -> unit 
    end 

module type SET = 
    sig 
    include Set.S 
    val format : Format.formatter -> t -> unit 
    end 

module MakeSet (P : POrderedType) : SET with type elt = P.t 

的實現是直截了當:

module MakeSet (P : OrderedType) = 
    struct 
    include Set.Make(P) 

    let format ff s = 
     let rec format' ff = function 
     | [] ->() 
     | [v] -> Format.fprintf ff "%a" format v 
     | v::tl -> Format.fprintf ff "%a,@ %a" format v format' tl in 
     Format.fprintf ff "@[<4>%[email protected]]" format' (elements s) 
    end 

我想要做類似的事情地圖。 POrderedType是好的鑰匙,但我需要的值的簡單類型:

module type Printable = 
    sig 
    type t 
    val format : Format.formatter -> t -> unit 
    end 

然後,我想做相似,我已經爲套做了什麼,但我遇到了以下問題。 Map.S值的類型爲+'a t。我無法想出一個方法來包含Map.S定義,同時將'a限制爲Printable.t。我要的是類似如下(忽略了一個事實,這是非法的):

module MakeMap (Pkey : POrderedType) (Pval : Printable) : 
    MAP with type key = Pkey.t and type 'a t = 'a t constraint 'a = Pval.t 

有沒有辦法做我想要的東西,而無需手動複製地圖的整個簽名?

回答

3

我認爲爲多態地圖建議打印功能的最簡潔的方法是使地圖打印功能參數化爲值打印功能。你可以認爲它是這樣的:

  • 仿函數定義的類型在函子級別定義,因此提供的功能對他們來說是最好的通過添加新仿函數的參數(或充實現有的)做

  • 參數化類型在價值層面的約束(廣義的),所以爲他們提供功能最好是通過增加新的參數值

在OCaml中完成,方便往往會使人在functorization時possi青睞參數多態性BLE。函數化有時需要強制執行某種類型的安全性(在這裏用於確保不同比較函數的映射具有不兼容的類型),但其他人則傾向於使用多態性。所以你在這裏真正處於幸運的境地。

如果你真的想要一個函子生成單形地圖,那麼恐怕你將不得不復制整個地圖界面,並將其應用於模擬情況 - 它沒有太多的工作。