2017-02-20 12 views
6

Tôi có một chức năng Erlang nhỏ mà so sánh nếu hai danh sách đều bình đẳng:Pattern khớp trong Haskell và Erlang

myEq([], [])   -> true; 
myEq([X|Xs], [X|Ys]) -> myEq(Xs, Ys); 
myEq(_, _)   -> false. 

Việc so sánh diễn ra trên dòng 2, X của [X|Xs] luôn liên kết với phần tử đầu tiên của danh sách đầu tiên, các đối sánh [X|Ys] chỉ khi các phần tử đầu tiên của cả hai danh sách đều bằng nhau.

Nếu tôi thử điều này trong Haskell, tôi nhận được thông báo lỗi: "Định nghĩa xung đột cho x". Một giải pháp khả thi trong Haskell sẽ là:

myEq (x:xs) (y:ys) = if x == y then myEq xs ys else False 

Nhưng tôi muốn biết nếu nó có thể làm điều này trong Haskell sử dụng kết hợp mô hình?

Trả lời

10

Không, trong Haskell bạn không thể sử dụng cùng một biến x trong phần đầu của mệnh đề. Haskell không không làm thống nhất hoặc kiểm tra bình đẳng như ví dụ tương ứng PrologErlang làm. Đây là quy định trong báo cáo Haskell '98:

Tập hợp các mô hình tương ứng với mỗi trận đấu phải tuyến tính --- không biến được phép xuất hiện nhiều hơn một lần trong toàn bộ.

(sao chép, in đậm thêm)

Cách duy nhất để làm điều đó là sử dụng một người bảo vệ (hoặc bất kỳ loại khác của kiểm tra trong cơ thể tất nhiên). tuy nhiên bạn có thể viết nó thêm thanh lịch như:

myEq [] [] = True 
myEq (x:xs) (y:ys) | x == y = myEq xs ys 
--     | otherwise = False 
myEq _ _ = False 

trường hợp otherwise thể được bỏ qua kể từ khi Haskell sẽ dự phòng trên mệnh đề cuối cùng và do đó trở False.

Hoặc thậm chí tao nhã hơn:

myEq [] [] = True 
myEq (x:xs) (y:ys) = x == y && myEq xs ys 
myEq _ _ = False 

Cá nhân tôi nghĩ rằng đó là tốt hơn vì ở đây bạn nêu rõ ràng rằng x bằng y nên những sai lầm như một cách tình cờ viết cùng một biến không thể xảy ra. Mặc dù tất nhiên nó là một vấn đề của hương vị.

+1

Để làm rõ: Erlang cũng không thống nhất. Nếu một biến xảy ra nhiều lần trong một mẫu, trình biên dịch Erlang chỉ tạo ra tên mới cho các lần xuất hiện khác và chèn một kiểm tra bảo vệ yêu cầu chúng bằng nhau, giống như bạn làm thủ công trong Haskell. – RichardC

+0

@RichardC: Tôi đã viết lại câu trả lời cho * thống nhất * và * kiểm tra bình đẳng *. Bạn có nghĩ rằng điều này giải quyết vấn đề này tốt hơn không? –

+0

Vâng, có vẻ tốt hơn. – RichardC

1

Không. Mỗi biến có thể bị ràng buộc nhiều nhất một lần ở bên khớp mẫu. Nếu bạn muốn liên kết một biến hai lần, bạn sẽ phải đánh giá để thực hiện thống nhất.

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