2014-05-11 16 views
5

tôi cố gắng sử dụng các loại tham số trong OCaml nhưng nó doesnt't việc :(loại tham số trong OCaml

Trong một tập tin đầu tiên "tree.ml" Tôi xác định loại:

type 'a tree = 
    | Node of ('a tree)*('a tree) 
    | Leaf of 'a 

Trong một nộp "intTree.ml", tôi sử dụng loại này khi bạn định nghĩa một kiểu t:

open Tree 
type t = int tree 

Cuối cùng, tôi muốn sử dụng các loại t trong một chức năng "kích thước" trong "main.ml":

open IntTree 

type r = IntTree.t 

let rec size tree = match tree with 
    | Leaf k -> 0 
    | Node (t1,t2) -> 1 + size t1 + size t2 

Khi tôi cố gắng biên soạn những tập tin này, tôi xin lỗi sau:

File "main.ml", line 6, characters 4-8: 
Error: Unbound constructor Leaf 

Nếu tôi định nghĩa "main.mli", nó không thay đổi bất cứ điều gì:

type r 

val size : r -> int 

Nếu tôi đặt:

let rec size (tree : r) = match tree with 
    | Leaf k -> 0 
    | Node (t1,t2) -> 1 + size t1 + size t2 

tôi có:

Warning 40: Leaf was selected from type Tree.tree. 
It is not visible in the current scope, and will not 
be selected if the type becomes unknown. 
... 

Tôi biết chúng là giải pháp để giải quyết lỗi này một cách nhanh chóng (ví dụ: đặt "cây mở t = int tree" trong main.ml thay vì "mở IntTree type t = IntTree.t") nhưng tôi cần sử dụng cấu trúc trước đó (vì các lý do khác ...). Có giải pháp nào không?

Cảm ơn bạn

+0

'Main.ml' của bạn mở' IntTree', vì vậy nó sẽ có tất cả các tên được định nghĩa ở đó. Tuy nhiên, 'Leaf' không được định nghĩa ở đó; nó được định nghĩa trong 'Tree'. Vì vậy, như Kadaku nói, bạn nên mở 'Tree' trong' main.ml' của bạn. Có vẻ như rất nhiều rắc rối, nhưng đó là vì các mô-đun của bạn quá nhỏ.Trong một dự án thực sự, bạn sẽ có nhiều tên để kiểm soát. –

+2

Ngoài ra, thay vì mở, cá nhân tôi thấy nó hữu ích hơn trong một dự án lớn để sử dụng tên đầy đủ, 'Tree.Leaf'. – nlucaroni

Trả lời

5

Bạn cần open Tree trong main.ml. Bạn không cần sao chép và dán khai báo kiểu. Trong trình biên dịch mã, bạn thử đoán xem bạn đang nghĩ gì. Đó là lý do tại sao việc thêm chú thích kiểu thủ công một phần giải quyết được vấn đề.

trình biên dịch thấy rằng bạn mong đợi tree là loại r, nó nhìn vào loại r từ mô-đun IntTree (được mở bởi bạn) và có nó hiểu rằng có lẽ chúng tôi có nhà thầu này trong Tree module. Nó mở nó với một cảnh báo. Tính năng này đã được giới thiệu khá gần đây, do đó, không được suprized rằng bạn không nhận thức được nó.

4

Một giải pháp khác là để thay đổi điều này:

open Tree 

này:

include Tree 

trong intTree.ml. Ý tưởng là intTree sau đó trở nên độc lập bằng cách bao gồm tất cả các định nghĩa từ Tree.

0

Trong khi thêm open Tree trong "main.ml" sẽ giải quyết vấn đề, nó có thể là thích hợp hơn để viết những điều sau đây để tránh gây ô nhiễm "main.ml" với các định nghĩa không liên quan cuối cùng từ "Tree.mli":

let rec size tree = match tree with 
    | Tree.Leaf k -> 0 
    | Tree.Node (t1,t2) -> 1 + size t1 + size t2