2013-09-23 2 views
1

(* 나는 더 많은 관심을가 명확하게하기 위해 내가 이전에 게시 된 질문을 재구성하고 유치하고 싶습니다 ... 나는 * ... 문제는 여전히 흥미로운 생각)재구성 이중 구현을 피하기 위해

다음과 같이 나는 모듈 형 ZONE을 정의 : 반복 계산을 피할 수 있도록 다양한 정보를 포함하는 데 사용됩니다 i: info

(* 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 

. Prop에서 Zone이 만들어지기 때문에 항상 동일하지는 않습니다. 여기

(* 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와 유형 PROP의 모듈에서 유형 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) 

문제는 이러한 2 개의 펑터의 유일한 차이점은 type infoget_prec (ZoneFun이 있으며, ZoneFunPrec은 그렇지 않음)입니다. 그들의 type proptype t은 동일하고, 그들의 기능은 f0, f1 ... (꽤 여러 가지가 있습니다) 정확히 동일합니다.

그래서 나는 f0, f1을 구현에서 방지하는 방법 궁금 등 두 번 ...

사람이를 달성하고 그들에게 의미있는 모듈/펑터 구조 조정의 아이디어가 있습니까?

+1

가능한 한 작은 문제를 시도하고 컴파일하십시오. 귀하의 코드는 응답자에게 너무 많은 의미없는 세부 사항을 포함하고 있으며, 완전하지는 않으며 편집 할 수 없습니다. ZoneFunPrec (ProcC)이 잘못되었습니다. ZoneFun (ProcC) – camlspotter

+0

방금 ​​개정 된 ZoneFun (ProcC)에 대해 정확합니다 ... – SoftTimur

답변

0

만 공유가 포함 된 모듈을 만들고 패턴 : 나는 당신의 진짜 f0 더 복잡하고 코드에서 다른 것들에 따라 여기에 생각

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

. (그렇지 않으면 별도로 컨텍스트 외부에서 정의 할 수 있습니다.) Propinfo과 같은 일부 무료 이름이 포함되어 있으므로 Shared은 실제로 컴파일 할 수 없습니다. 그것의 매개 변수에서 이러한 이름을 소요 펑에 변경 :

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 펑터를 사용하여 코드 중복을 방지 할 수 있습니다.여기 유형 별칭 info_

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

가 순환 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