2016-01-22 13 views
6

Tôi mới tham gia OCaml và đọc cuốn sách Real World OCaml (RWO). Kết hợp mẫu được mô tả trong chương 3 và có vẻ yếu so với mô hình của Erlang (hoặc Prolog).Tại sao mẫu của OCaml lại yếu hơn so với Erlang?

Câu hỏi của tôi là:

  1. tại sao mô hình OCaml của phù hợp với yếu?
  2. có lợi thế nào đối với kiểu kết hợp mẫu của OCaml không?

Một ví dụ cụ thể:

Chức năng sau (. Lấy từ RWO p 63) destutters một danh sách

let rec destutter list = 
    match list with 
    | [] -> [] 
    | [hd] -> [hd] 
    | hd :: hd' :: tl -> 
     if hd = hd' then ds1 (hd' :: tl) 
     else hd :: ds1 (hd' :: tl) 
    ;; 

# destutter [1;2;3;3;4;5;5;6];; 
- : int list = [1; 2; 3; 4; 5; 6] 

Trong Erlang nó sẽ có thể (và tôi nghĩ ưa thích) để sử dụng mô hình khớp với thay vì có điều kiện:

destutter([])  -> []; 
destutter([X])  -> [X]; 
destutter([H,H|T]) -> destutter([H|T]); 
destutter([H|T]) -> [H | destutter(T)]. 

Đang thử loại điều này trong OCaml ...

let rec destutter list = 
    match list with 
    | [] -> [] 
    | [hd] -> [hd] 
    | hd :: hd :: tl -> destutter tl (* error *) 
    | hd :: tl -> hd :: destutter tl 
    ;; 

... đặt ra một lỗi trên dòng đánh dấu:

Error: Variable hd is bound several times in this matching 

Vì vậy, Erlang/Prolog kiểu mẫu phù hợp với không hoạt động trong OCaml. Tại sao? Ưu điểm của phương pháp OCaml là gì?

Với cảm ơn và lời chúc tốt nhất

Ivan

+0

Câu hỏi rất thú vị, tôi chắc chắn cần tìm hiểu thêm về Erlang! –

Trả lời

5

Các mô hình Erlang là mạnh mẽ hơn bởi vì nó có thể phù hợp với một cái gì đó xác định tại thời gian chạy. Các mẫu OCaml khớp với mọi thứ cố định tại thời gian biên dịch. Nó sau đó các mẫu OCaml có thể có thể được thực hiện để đi nhanh hơn. Tôi cũng tìm thấy các mẫu kiểu OCaml dễ dàng hơn để giải thích.

+1

Cảm ơn câu trả lời của bạn! Ba câu trả lời rất tốt và rất khó để quyết định nên chấp nhận. - Bạn thấy các mẫu kiểu OCaml dễ hiểu hơn vì bạn quen với OCaml hơn với Erlang? Làm thế nào tôi có thể phát triển để yêu mến các PM của OCaml, đến từ Erlang? –

4

Các mẫu trong OCaml được biên dịch thành một mã rất hiệu quả với rất nhiều sophisticated optimizations. Bjarne Stroustrup thậm chí là bragged mà họ đã viết một cái gì đó có thể so sánh được trong một số trường hợp nhất định trong C++. Nhưng nói chung, mẫu matcham OCaml nhanh hơn nhiều. Và quyến rũ của nó để nhìn vào đầu ra lắp ráp. Và có lẽ Erlang cung cấp sự linh hoạt hơn, nhưng nó được mong đợi từ một ngôn ngữ động. Nếu không thì tại sao lại sử dụng chúng.

Có vấn đề khác nữa. Các mẫu được khớp với cấu trúc. Nếu bạn muốn khớp với [H,H|T], bạn đang thực sự gọi so sánh hai phần tử đầu tiên. Trong hầu hết các trường hợp, chức năng so sánh sẽ do người dùng cung cấp và không được biết trước.

+0

Cảm ơn câu trả lời của bạn! Ba câu trả lời rất tốt và rất khó để quyết định nên chấp nhận. –

+0

Bài viết về tối ưu hóa kết hợp mẫu thật thú vị, cảm ơn bạn đã viết câu trả lời này! –

8

Trước tiên, bạn luôn có thể nắm bắt được sự bình đẳng giữa các biến mô hình thông qua một điều khoản when trong OCaml, ví dụ .:

let rec destutter = function 
    | []    -> [] 
    | [hd]   -> [hd] 
    | hd :: hd' :: tl 
     when hd = hd' -> destutter (hd :: tl) 
    | hd :: hd' :: tl -> hd :: destutter (hd' :: tl) 

Có một trade-off đây. Trong khi Erlang là biểu cảm hơn, kết hợp mẫu OCaml đơn giản hơn (có nghĩa là định nghĩa ngôn ngữ đơn giản, trình biên dịch, v.v.) và bạn vẫn có thể làm những gì bạn cần (với chi phí viết nhiều mã hơn).

Lưu ý rằng trong khi bạn có thể viết lại mẫu không tuyến tính dưới dạng mẫu tuyến tính với mệnh đề khi, thì đó không phải là vấn đề chính.Quan trọng hơn, việc khớp mẫu sau đó cần có khái niệm bình đẳng cho các kiểu tùy ý để hỗ trợ các mẫu phi tuyến tính. Đây không phải là một vấn đề trong Erlang, nhưng OCaml không chỉ có = vs == tích hợp (cấu trúc bình đẳng so với danh tính), nhưng đối với bất kỳ loại nào, nó có thể không phải là loại bình đẳng mà bạn cần (nghĩ dây và trường hợp độ nhạy, ví dụ). Sau đó, kết quả là việc kiểm tra mức độ đầy đủ hoặc chồng chéo sẽ trở nên không tầm thường. Cuối cùng, nó có vấn đề liệu việc cung cấp một trường hợp đặc biệt cho một loại hình bình đẳng cụ thể có đáng giá không, vì có bao nhiêu mối quan hệ hữu ích giữa các phần của một mẫu có thể có. (Tôi lưu ý rằng các ngôn ngữ không nghiêm ngặt có các vấn đề khác.)

Ngoài ra, kết hợp mẫu của Prolog là hợp nhất và mạnh hơn Erlang hoặc OCaml (nhưng cũng khó thực hiện hơn).

+1

Cảm ơn câu trả lời của bạn! Ba câu trả lời rất tốt và rất khó để quyết định nên chấp nhận. - khi mệnh đề có sẵn trong Erlang quá (gọi là bảo vệ). Một ví dụ tương tự như của bạn đến một chút sau đó trong cuốn sách RWO, nhưng tôi sẽ bỏ lỡ các PMs kiểu Erlang: ( –

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