2017-10-17 79 views
2

我最終試圖做的事情是1)限制對模塊(因此mli文件)的可見性和2)定義一個函子,其中參數具有「規範實現「,它作爲一個ml/mli對生活在源碼樹中,並堅持參數具有與此規範實現相同的形狀。mml文件和ml文件裏簽名之間的OCaml共享結構

假設我有一個包含字符串連接

(* concat.ml *) 
type t = string 
let concat x y = x^y 

單一功能的文件concat.ml和我有一個接口,它

(* concat.mli *) 
type t 
val concat : t -> t -> t 

不過,我也有一個仿函數join,看起來像這並且期望與Concat具有相同形狀的東西。 (中join實施是故意天真):

(* join.ml *) 
module Join(X : Concat_type.TYPE) : sig 
    val join : X.t list -> X.t 
end = struct 
    let rec join xs = match xs with 
    | [] -> failwith "can't be empty" 
    | [x] -> x 
    | [x; y] -> X.concat x y 
    | (x::xs') -> X.concat x (join xs') 
end 

爲了表達「相同形狀的毗連」的約束,我只好再拍ml文件concat_type.ml看起來像這樣:

(* concat_type.ml *) 
module type TYPE = sig 
    type t 
    val concat : t -> t -> t 
end 

Concat_type.TYPEConcat mli在這種情況下幾乎相同。我所做的concat_type.ml的唯一原因是爲了支持函子Join,並明確限制它可以看到的內容,如果我嘗試將其應用於模塊執行concat的模塊。

有沒有辦法將Concat_type.TYPE導入到Concat界面,反之亦然,或者有其他方式避免它們之間的重複?

+1

你應該能夠只使用'包括Concat_type.TYPE'在concat.mli,我覺得 – glennsl

+2

你可以用'Concat'的模塊類型,例如,'模塊加入(X:Concat的模塊類型):sig ...'。 – gsg

回答

1

是的,可以通過Concat_type.TYPE模塊類型表示Concat模塊接口。也可以獲得現有模塊的模塊類型。

第一種方法是這樣的:

(* concat.mli *) 
include Concat_type.TYPE 

第二個方法讓你擺脫Concat_type的,但我個人不喜歡它,因爲我不喜歡module type of結構。但儘管如此,有一種可能性:

module type Concat = module type of Concat 

module Join (X : Concat) = struct 
    ... 
end