2010-07-25 31 views
8

Tôi khá khó khăn với vấn đề functor sau trong OCaml. Tôi dán một số mã chỉ để cho bạn hiểu. Về cơ bảnTìm hiểu về các thư viện trong OCaml

tôi xác định hai mô-đun trong 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 

và functor sau:

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

Sau đó, để thực sự sử dụng các mô-đun tôi xác định một mô-đun mới trực tiếp trong một tập tin gọi là 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 *) 

Từ nguồn thứ ba (formulas.ml) tôi đã sử dụng functor với Prism mô-đun:

module PrismPctl = Pctl.Make(Prism) 
open PrismPctl 

Và cuối cùng từ main.ml

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

và biên dịch cung cấp cho các lỗi sau

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

Từ những gì tôi có thể hiểu được có một loại bí danh xấu của các tên, chúng giống nhau (vì value array là loại được định nghĩa là t và nó 's được sử dụng M with type s = P.t trong functor) nhưng kiểm tra loại không xem xét chúng giống nhau.

Tôi thực sự không hiểu vấn đề ở đâu, ai cũng có thể giúp tôi?

Cảm ơn trước

+0

Tôi không biết đủ về OCaml để giúp đỡ, nhưng nó có thể là câu hỏi trước đây là một vấn đề tương tự? http://stackoverflow.com/questions/640510/functors-in-ocaml – Gian

+0

@Gian: đó là cùng một vấn đề gốc, nhưng nếu bạn hiểu điều đó, bạn đã sẵn sàng trên con đường của bạn để không cần phải đặt câu hỏi trong địa điểm đầu tiên. – Gilles

Trả lời

6

(Bạn đăng mã không thể biên dịch. Đó là một ý tưởng tồi vì nó có thể khiến mọi người khó giúp bạn hơn, và vì việc giảm sự cố xuống một ví dụ đơn giản đôi khi là đủ để giải quyết nó. khó khăn của bạn anyway.)

Bên trong formulas.ml, Ocaml có thể thấy rằng PrismPctl.s = Pctl.Make(Prism).t = Prism.t; sự bình đẳng đầu tiên là từ định nghĩa của PrismPctl và bình đẳng thứ hai là từ chữ ký của Pctl.Make (cụ thể là bit with type s = P.t).

Nếu bạn không viết một tệp mli cho Formulas, mã của bạn nên biên dịch. Vì vậy, vấn đề phải là tệp .mli bạn đã viết không đề cập đến sự bình đẳng đúng.Bạn không hiển thị .mli tập tin của bạn (bạn nên, chúng là một phần của vấn đề), nhưng có lẽ bạn đã viết

module PrismPctl : Pctl.M 

Đó không phải là đủ: khi trình biên dịch biên dịch main.ml, nó sẽ không biết gì về PrismPctl không được chỉ định trong formulas.mli. Bạn cần phải xác định một trong hai

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

hoặc, giả sử bạn đã bao gồm with type s = P.t trong chữ ký của Make trong pctl.mli

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

Đó là vấn đề. Tôi nhận ra nó ngày hôm qua bằng cách nhìn vào câu trả lời đưa ra câu hỏi liên kết bởi gian bên trong bình luận. Tôi đã không dán tập tin '.mli' của mình vì quên làm nó .. lỗi của tôi! Cảm ơn bạn – Jack

2

Đây là vấn đề mà tôi cũng gặp phải khi tìm hiểu thêm về các vấn đề này. Khi bạn tạo functor, bạn để lộ chữ ký của functor, trong trường hợp này là M. Nó chứa một kiểu trừu tượng s, được tham số hóa bởi hàm functor, và bất cứ điều gì cụ thể hơn không được tiếp xúc với bên ngoài. Do đó, việc truy cập bất kỳ phần tử bản ghi nào của s (như trong sys_state) sẽ dẫn đến lỗi loại, như bạn đã gặp phải.

Phần còn lại có vẻ ổn. Nó chắc chắn là khó để có được vào sử dụng functors đúng, nhưng hãy nhớ rằng bạn chỉ có thể thao tác các trường hợp của các loại tham số của functor thông qua giao diện/chữ ký được tiếp xúc bởi các functor.

Các vấn đề liên quan