2010-10-29 27 views
5

Tại sao kịch bản lệnh Haskell sau đây không hoạt động như mong đợi?Các biến trong Haskell

find :: Eq a => a -> [(a,b)] -> [b] 
find k t = [v | (k,v) <- t] 

Với find 'b' [('a',1),('b',2),('c',3),('b',4)], người phiên dịch trả [1,2,3,4] thay vì [2,4]. Sự ra đời của một biến mới, dưới đây gọi u, là cần thiết để có được điều này để làm việc:

find :: Eq a => a -> [(a,b)] -> [b] 
find k t = [v | (u,v) <- t, k == u] 

Có ai biết lý do tại sao phiên bản đầu tiên không tạo ra kết quả mong muốn?

+0

Lặp lại sau tôi: không có biến nào trong Haskell. ;-) Đây là các ký hiệu hoặc số nhận dạng. Các biến có nghĩa là biến đổi. Trong Haskell, mọi thứ đều không thay đổi. –

+9

@Konrad Rudolph: Báo cáo Haskell 98 sử dụng thuật ngữ "biến" trên khắp nơi. Điều quan trọng cần lưu ý rằng điều này không có nghĩa là những gì bạn có thể mong đợi, nhưng tôi không nghĩ là có nhiều sự kiên trì hơn so với tài liệu chuẩn là cần thiết. –

+4

@Konrad Rudolph: Chắc chắn bạn thích thú! Tại sao, tôi đã tìm thấy toàn bộ phần về các biến [trong một số Haskell, ngay tại đây] (http://books.google.com.vn/books?id=27dkTJFrLZIC&pg=PA111). –

Trả lời

14

Từ Haskell 98 Report:

Như thường lệ, các ràng buộc trong danh sách comprehensions thể shadow những người trong phạm vi bên ngoài; ví dụ:

[ x | x <- x, x <- x ] = [ z | y <- x, z <- y]

Một điểm khác: nếu bạn biên dịch với -Wall (hoặc cụ thể với -fwarn-name-shadowing) bạn sẽ nhận được cảnh báo sau đây:

Warning: This binding for `k' shadows the existing binding 
      bound at Shadowing.hs:4:5 

Sử dụng -Wall thường là tốt ý tưởng - nó thường sẽ làm nổi bật những gì đang diễn ra trong những tình huống khó hiểu như thế này.

+0

+1 cho gợi ý cờ trích dẫn và cảnh báo –

+0

Tôi nghĩ rằng vấn đề không phải là về bóng tối.Đó là về ý nghĩa của số nhận dạng trong mẫu ở vị trí đầu tiên - rằng nó không khớp với giá trị của biến với mã định danh đó, mà là khớp với bất kỳ thứ gì và liên kết giá trị với biến mới với idenfier đó – newacct

11

Kết hợp mẫu (k,v) <- t trong ví dụ đầu tiên tạo hai biến cục bộ mới vk được điền với nội dung của bộ tóan t. So khớp mẫu không so sánh nội dung của t với biến đã tồn tại k, nó tạo ra một biến mới k (ẩn biến bên ngoài).

Nói chung không bao giờ có "thay thế biến" xảy ra trong một mẫu, bất kỳ tên biến nào trong một mẫu luôn tạo các biến cục bộ mới.

3

Bạn chỉ có thể đối sánh mẫu trên chữ và các hàm tạo.
Bạn không thể đối sánh trên các biến. Đọc thêm here.

Điều đó đang được nói, bạn có thể quan tâm đến các kiểu xem.

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