2013-03-23 25 views
10

Tôi có một hàm với hai đối số mà tôi phải đối sánh với mẫu. Nếu tôi sử dụng currying trên mô hình đầu tiên nó sẽ không biên dịch:Tại sao tôi có thể cà ri một trong các mẫu nhưng không phải mẫu khác trong mẫu của tôi?

drop' :: Int -> [a] -> [a] 
    drop' 0 = id -- ghci: "Equations for drop' have different numbers of arguments" 
    drop' n (x:xs) = drop' (n-1) xs 

Trình biên dịch cho kết quả này:

99.hs:106:3: 
Equations for drop' have different numbers of arguments 
    99.hs:106:3-15 
    99.hs:107:3-33 
In an equation for `split': 
    split xs n 
     = (take' n xs, drop' n xs) 
     where 
      take' 0 _ = [] 
      take' n (x : xs) = x : take (n - 1) xs 
      drop' 0 = id 
      drop' n (x : xs) = drop' (n - 1) xs 
Failed, modules loaded: none. 

Nếu tôi chỉ cung cấp cho các mô hình cà ri, tuy nhiên, sau đó nó biên dịch:

drop' :: Int -> [a] -> [a] 
    drop' 0 = id -- compiles 

Điều gì mang lại?

+1

Giả sử bạn biết bạn chỉ cần viết 'thả' 0 x = x'? – Koterpillar

+3

Tất cả các phương trình xác định hàm phải có cùng số đối số. Vì vậy, 'thả 0 = id; thả n = \ (_: xs) -> thả (n-1) xs' sẽ biên dịch. –

+4

[Lưu ý rằng tất cả các mệnh đề xác định một hàm phải tiếp giáp, ** và số mẫu trong mỗi mệnh đề phải giống nhau. **] (http://www.haskell.org/onlinereport/haskell2010/haskellch4.html# x10-830004.4.3) –

Trả lời

10

Lời giải thích duy nhất tôi có thể tìm thấy (http://www.haskell.org/pipermail/haskell-cafe/2009-March/058456.html):

Vấn đề là hầu hết cú pháp, theo nghĩa rằng hầu hết các lần xuất hiện của định nghĩa với một số khác nhau của các đối số lỗi chính tả đơn giản. Các khác có thể là vấn đề triển khai: nó làm cho các quy tắc đối sánh mẫu phức tạp hơn.

+0

Dường như với tôi rằng rất nhiều suy nghĩ đã đi vào các Báo cáo Haskell khác nhau về cách bảo vệ chống lại lỗi lập trình viên, mà không phải hy sinh những gì bạn có thể diễn đạt bằng ngôn ngữ. Xem thêm bình luận của Daniel Fischer, và ngay cả giới hạn độc ác đáng sợ rơi vào thể loại này. Đó là một rắc rối nhỏ bây giờ, nhưng bạn sẽ được biết ơn cho nó sau này. – yatima2975

+0

@ yatima2975 Tôi có thể hiểu được muốn nip lỗi lập trình phổ biến trong chồi. Nhưng nó không thể chỉ là một cảnh báo trình biên dịch? Mặc dù tôi đoán có một loạt cảnh báo trình biên dịch cũng có thể gây khó chịu (chưa kể các chú thích tiềm ẩn để ngăn chặn chúng), vì vậy tôi đoán đó là một thỏa hiệp khá tốt vì tôi không thể tưởng tượng được trường hợp mã sẽ ít rõ ràng hơn hạn chế nhỏ này. – Guildenstern

1

Tôi không thể cho bạn biết lý do tại sao chắc chắn, nhưng đây là giới hạn đã biết. Tất cả các trường hợp của cùng một hàm phải có cùng số đối số.

1

Đây là một khó chịu "tính năng" của GHC, để chắc chắn, nhưng để sửa chữa nó, bạn có thể làm điều này:

drop' n = \(x:xs) -> drop' (n-1) xs 

Bạn phải cà ri cả hay không, và cả hai cùng số lượng đối số. Nếu đây là một kiểm tra lint, đó là tuyệt vời: nhưng tôi muốn có một tùy chọn trình biên dịch để bật/tắt nó.

+2

Vì điều này giống hệt với định nghĩa khác (và thực sự tiết lộ nhiều hơn), nó đánh bại điểm IMHO một chút. – jozefg

+0

@jozefg Tôi đã đăng bài này vì tôi không thể hiểu được các câu trả lời khác mà không cần điều tra thêm: một quan điểm thay thế thường hữu ích. – jpaugh