2012-03-19 28 views

Trả lời

10

Đây là một trong những phần phiền phức của cú pháp OCaml, theo ý kiến ​​của tôi. Mặc dù có vẻ bề ngoài, nhà xây dựng Foo không yêu cầu 2-tuple làm đối số của nó. Nó đòi hỏi, cú pháp, hai giá trị trong dấu ngoặc đơn - nhưng chúng không phải là một bộ tuple. Vì vậy, nó chỉ đơn giản là trường hợp mà t có loại sai. Cách làm cho tác phẩm này là để nói:

let (a, b) = t in Foo (a, b) 

Vấn đề thực sự là dấu ngoặc đơn đang được sử dụng cho hai thứ khác nhau (hoặc vì vậy tôi yêu cầu). Một khi bạn quen với việc này, nó không quá khó để giải quyết.

Sửa: nếu bạn muốn constructor Foo để có một tuple duy nhất, chứ không phải là hai giá trị riêng biệt, bạn có thể định nghĩa nó như thế này:

type foo = Foo of (int * int) 

Sau đó, phần còn lại của mã ban đầu của bạn sẽ công việc.

+1

Dấu ngoặc đơn được sử dụng cho hơn hai thứ! Chúng cũng làm cho ví dụ của OP hoạt động như là nếu anh ta chỉ thay đổi 'type foo = Foo của (int * int)' –

+0

Vâng, tôi đã thêm nó vào phần chỉnh sửa ngay trước khi bạn bình luận (không phải là tôi cần lấy tín dụng hay gì cả :-). –

+0

Cảm ơn bạn đã giải thích! – Ricardo

4

Lưu ý rằng sự khác biệt giữa Foo of (a * b)Foo of a * b là vì lý do hiệu quả: Foo of (a * b) có đối số là một bộ tuple, con trỏ đến hai phần tử trong heap. Foo of a * b có hai đối số được đóng gói trực tiếp với thẻ, tránh một sự gián đoạn.

Đây cũng là lý do tại sao, ví dụ, các thuật toán sử dụng danh sách liên kết (ví dụ Hashtables với xô danh sách liên kết) đôi khi xác định kiểu dữ liệu riêng của họ thay vì tái sử dụng ('a * 'b) list:

type ('a, 'b) assoc_list = 
    | Nil 
    | Cons of 'a * 'b * ('a, 'b) assoc_list 

Tất nhiên trong chung trường hợp cấp cao như vậy chuyên môn không phải là cực kỳ quan trọng (và có thể cản trở tái sử dụng mã), nhưng nó vẫn tốt đẹp để có thể nhận được xuống các chi tiết kỹ thuật như vậy khi bạn thực sự cần kiểm soát chặt chẽ hơn đại diện bộ nhớ.

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