2013-09-23 56 views
1

(*我想重新制定,我以前張貼的問題,以使其更清晰,並吸引了更多的關注。我認爲這個問題仍然是有趣。*)重組2個仿函數,以避免重複執行

我已經定義了一個模塊式ZONE如下:

(* part of zone.ml *) 
module type ZONE = 
sig 
    type info 
    type prop 
    type t = { s: string; p: prop; i: info } 
    val f1 : t -> string 
end 

其中i: info用於包含各種信息,這有助於避免重複計算。它不會總是相同的,因爲它取決於構建ZoneProp。舉例來說,這裏是從PROP類型的模塊構建ZONE類型的模塊Zone一個仿函數,一個基本info

(* part of zone.ml *) 
module ZoneFun (Prop : PROP) = struct 
    type info = { a: int } 
    type prop = Prop.t 
    type t = { s: string; p: prop; i: info } 
    let f0 z = "f0" 
    ... 
end 

這裏是另一個函子來構建ZONE類型的模塊Zone,具有相對更復雜的info

(* zoneFunPrec.ml *) 
module ZoneFunPrec (Prop: PROP) (Prec: ZONESM) = struct 
    type info = { a: int; b: Prec.t } 
    type prop = Prop.t 
    type t = { s: string; p: prop; i: info } 
    let get_prec z = z.info.prec 
    let f0 z = "f0" 
    ... 
end 

那麼我可以用仿函數如下:

module ZoneC = ZoneFun(PropC) 
module ZoneA = ZoneFunPrec(PropA)(ZonesmB) 

問題是,type infoget_precZoneFun有它,而ZoneFunPrec還沒有)是這兩個函子的唯一區別;他們的type proptype t是相同的,他們的功能f0,f1 ...(有很多)也是一樣的。

所以我想知道如何從執行f0f1避免等兩次......

沒有人有重組模塊/仿函數來實現這一點,並讓他們有意義的想法?

+1

請嘗試問題儘可能的小,並使其編譯。你的代碼包含了太多無意義的細節給答覆者,而不是完整的,而且不是可編譯的。 ZoneFunPrec(ProcC)是錯誤的。它必須是ZoneFun(ProcC) – camlspotter

+0

你是對的'ZoneFun(ProcC)',剛剛修改... – SoftTimur

回答

0

創建一個模塊只包含共享圖案:

module Shared = struct 
    type prop = Prop.t 
    type t = { s: string; p: prop; i: info } 
    let f0 z = "f0" 
    ... 
end 

我相信在這裏你真正f0較爲複雜,取決於你的代碼的其他事情。 (否則它可以單獨定義在上下文之外)

該模塊Shared由於包含一些免費名稱,如Propinfo,因此不是真正可編譯的。將其更改爲一個仿函數,從它的參數取這些名字:

module MakeShared(A : sig 
    module Prop : sig 
    type t 
    end 
    type info 
end) = struct 
    type prop = Prop.t 
    type t = { s : string; p : prop; i : info } 
    let f0 z = "f0" 
    ... 
end 

,可能需要更多的東西在簽名A。這取決於你省略的代碼。

您可以在ZoneFunZoneFunPrec的主體中使用此MakeShared仿函數以避免代碼重複。它應該是這樣的:

module ZoneFun (Prop : PROP) = struct 
    type info = { a: int } 
    type info_ = info 
    include MakeShared(struct 
    module Prop = Prop 
    type info = info_ 
    end) 
end 

這裏的類型別名info_需要避免的循環recusvie類型定義type info = info。不像module這是不遞歸的,因此module Prop = Prop按預期工作,type聲明總是遞歸的。

這是重構代碼的一種方法。可能有其他的,但是從你的僞代碼中不是很清楚。例如,您可能能夠使用MakeShared不仿函數內部,而是在那裏你創建一個實際的實例模塊:

module ZoneC = struct 
    include SmallerZoneFun(PropC) 
    include MakeShared(...) 
end 
+0

謝謝...會讓你知道它是否合適... – SoftTimur

+0

這樣的作品,謝謝你... – SoftTimur

0

對不起,我沒有給你確切的代碼,但不能你堅持的常見功能在自己module然後include它想:

module type ZONE = 
sig 
    type info 
    type prop 
    type t = { s: string; p: prop; i: info } 
    include ZoneFunCommon 
end