2011-10-04 2 views
7
test :: String -> String -> Int 

test' x y n = n 
test' "" (y:ys) n = error "error" 
test' (x:xs) "" n = error "error" 
test' (x:xs) (y:ys) n = 
     if  x == y 
     then test' xs ys n 
     else test' xs ys (n+1) 
test a b = test' a b 0 

Khi tôi biên dịch này, tôi nhận ra điều này:Haskell - khớp mẫu (es) được chồng chéo

Warning: Pattern match(es) are overlapped 

Và câu trả lời luôn là "0", mà không phải là những gì tôi mong đợi. Vấn đề với mã và cách khắc phục nó là gì?

Trả lời

9

test' x y n = n sẽ khớp với mọi cuộc gọi, các mẫu khác sẽ không được xem xét. Tôi nghĩ trường hợp này phải là test' "" "" n = n. Bạn nhận được kết quả tương tự nếu bạn di chuyển dòng ban đầu của mình tại số kết thúc (khi tất cả các trường hợp khác không thành công), nhưng sau đó bạn nên viết test' _ _ n = n cho thấy rằng bạn cố ý bỏ qua một số đối số.

[Chỉnh sửa]

Một giải pháp ngắn hơn sẽ là:

test a b | length a == length b = sum $ map fromEnum $ zipWith (/=) a b 
     | otherwise = error "error" 

Khái niệm zipWith tạo ra một danh sách các Bool đó là True cho mọi sự khác biệt. Chức năng fromEnum bản đồ False đến 0True đến 1.

+0

Rất hữu ích! Tôi đã học được rất nhiều! Cảm ơn – Ferry

7

Các mẫu được thử theo thứ tự. Mẫu đầu tiên của bạn cho test' luôn phù hợp, vì vậy trường hợp đó luôn được sử dụng. Trường hợp đầu tiên có lẽ là

test' "" "" n = n 

thay thế.