2010-07-25 4 views
8

OCaml에서 다음과 같은 펑터 문제가 있습니다. 내가 이해할 수 있도록 일부 코드를 붙여 넣습니다. 기본적으로 OCaml의 펑터 이해하기

나는 pctl.ml이 두 모듈을 정의 :

module type ProbPA = sig 
    include Hashtbl.HashedType 
    val next: t -> (t * float) list 
    val print: t -> float -> unit 
end 

module type M = sig 
    type s 
    val set_error: float -> unit 
    val check: s -> formula -> bool 
    val check_path: s -> path_formula -> float 
    val check_suite: s -> suite -> unit 
end 

다음과 같은 펑터 :

다음
module Make(P: ProbPA): (M with type s = P.t) = struct 
    type s = P.t 
    (* implementation *) 
end 

실제로 내가 prism.ml라는 파일에 직접 새 모듈을 정의 된이 모듈을 사용하기를 :

type state = value array 
type t = state 
type value = 
    | VBOOL of bool 
    | VINT of int 
    | VFLOAT of float 
    | VUNSET 
(* all the functions required *) 

세 번째 소스가) 내가 Prism 모듈로 펑터를 사용 :

module PrismPctl = Pctl.Make(Prism) 
open PrismPctl 

그리고 마지막으로 main.ml에서

open Formulas.PrismPctl 
(* code to prepare the object *) 
PrismPctl.check_suite s.sys_state suite (* error here *) 

및 컴파일 다음과 같은 오류 나는 일종의가 이해할 수있는 일부터

Error: This expression has type Prism.state = Prism.value array but an expression was expected of type Formulas.PrismPctl.s

에게 제공 이름의 잘못된 앨리어싱은 동일합니다 (value arrayt으로 정의 된 유형이므로 '는 펑터에서 M with type s = P.t을 사용했습니다.)하지만 형식 검사기는 그것들을 동일하게 간주하지 않습니다.

나는 정말로 어디에 문제가 있는지 이해하지 못해 누구도 나를 도울 수 있습니까? 사전

+0

Make의 서명에 with type s = P.t을 포함 가정 내가 OCaml의 도와 대해 충분히 모르겠지만, 가능하다이 이전 질문은 비슷한 문제인가? http://stackoverflow.com/questions/640510/functors-in-ocaml – Gian

+0

@Gian : 그것은 근본적인 문제는 같지만, 이해한다면, 당신은 이미 당신의 질문에 질문 할 필요가 없습니다. 처음. – Gilles

답변

6

(컴파일 할 수없는 코드를 게시하는 경우 사람들에게 도움을 줄 수 있고 간단한 예제로 문제를 해결할 때가끔 해결하기에 충분하지 않기 때문에 좋지 않은 생각입니다. 어쨌든 당신의 어려움)

formulas.ml 안에, Ocaml은 PrismPctl.s = Pctl.Make(Prism).t = Prism.t을 볼 수 있습니다; 첫 번째 평등은 PrismPctl의 정의에서 비롯되며 두 번째 동등 함은 Pctl.Make (특히 with type s = P.t 비트)의 서명에서 비롯됩니다.

Formulasmli 파일을 쓰지 않으면 코드를 컴파일해야합니다. 문제는 여러분이 작성한 .mli 파일에 올바른 평등이 언급되어 있지 않아야한다는 것입니다.당신은 (당신이 그들이 문제의 일부 야한다) 당신의 .mli 파일을 표시하지 않지만, 아마도 당신은 충분하지 않아 그

module PrismPctl : Pctl.M 

를 썼다 : 컴파일러가 main.ml를 컴파일 할 때, 그것은 PrismPctl을에 대해 아무것도 알 수 없습니다 이는 formulas.mli에 지정되어 있지 않습니다. 당신도

module PrismPctl : Pctl.M with type s = Prism.t 

를 지정해야하거나, 당신이 pctl.mli

module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s 
+0

그것이 문제였습니다. 나는 어제 그 의견을보고 대답 안에 gian에 의해 링크 된 질문을 제공함으로써 깨달았다. 내 .mli 파일을 붙여 넣지 않았기 때문에 잊어 버렸습니다. 내 잘못! 고맙습니다 – Jack

2

에서

덕분에이 다음에 대한 자세한 내용을 배울 때 나뿐만 아니라에 달린 문제입니다. 펑터를 만들면 펑터의 서명이 노출됩니다 (이 경우 M). 그것은 functor에 의해 매개 변수화 된 추상 유형 s을 포함하며 더 구체적 인 것은 외부에 노출되지 않습니다. 따라서 s의 레코드 요소에 액세스하면 (예 : sys_state) 유형 오류가 발생합니다.

나머지는 괜찮아 보입니다. 펑터를 올바르게 사용하는 것은 확실히 어렵지만, 펑터에 의해 노출 된 인터페이스/서명을 통해 펑터에 의해 매개 변수화 된 유형의 인스턴스 만 조작 할 수 있다는 것을 기억하십시오.