2013-04-22 21 views
12
isPalindrome :: [a] -> Bool 
isPalindrome xs = case xs of 
         [] -> True 
         [x] -> True 
         a -> (last a) == (head a) && (isPalindrome (drop 1 (take (length a - 1) a))) 

main = do 
    print (show (isPalindrome "blaho")) 

kết quả trongHaskell: Không dụ cho (Eq a) phát sinh từ việc sử dụng của `=='

No instance for (Eq a) 
    arising from a use of `==' 
In the first argument of `(&&)', namely `(last a) == (head a)' 
In the expression: 
    (last a) == (head a) 
    && (isPalindrome (drop 1 (take (length a - 1) a))) 
In a case alternative: 
    a -> (last a) == (head a) 
     && (isPalindrome (drop 1 (take (length a - 1) a))) 

Tại sao lỗi này xảy ra?

+1

chức năng của bạn giả định 'a' có thể được so sánh với '==', bạn phải đặt thông tin này vào chữ ký loại. –

+0

Bởi vì '(==)' là một thành viên của lớp 'Eq'. Vì vậy, bạn có thể sử dụng nó chỉ trên các loại là các trường hợp của 'Eq'. –

+1

Real world haskell chap 3? Tôi cũng vậy! – Jason

Trả lời

27

Bạn đang so sánh hai mục thuộc loại a bằng cách sử dụng ==. Điều đó có nghĩa là a không thể là bất kỳ loại nào - nó phải là một phiên bản của Eq, vì loại ==(==) :: Eq a => a -> a -> Bool.

Bạn có thể khắc phục điều này bằng cách thêm một hạn chế Eq trên a với loại chữ ký của chức năng của bạn:

isPalindrome :: Eq a => [a] -> Bool 

Bằng cách này, có một cách đơn giản hơn nhiều để thực hiện chức năng này sử dụng reverse.

+8

Theo lambdabot, 'isPalindrome = reverse >> = (==)': D – fredoverflow

+1

@FredOverflow Wow, điều đó thật mơ hồ. :) – augustss

+1

Nó sử dụng cá thể đơn lẻ cho các hàm, giống như 'join (+) 2 = 4'. Nhưng 'isPalindrome xs = xs == đảo ngược xs' là hoàn toàn hợp lý. –

0

giải thích về hammar là chính xác.

Một ví dụ đơn giản:

nosPrimeiros :: a -> [(a,b)] -> Bool 
nosPrimeiros e [] = False 
nosPrimeiros e ((x,y):rl) = if (e==x) then True 
             else nosPrimeiros e rl 

Các (e == x) sẽ thất bại cho chữ ký chức năng này. Bạn cần phải thay thế:

nosPrimeiros :: a -> [(a,b)] -> Bool 

thêm một thể hiện Eq cho một

nosPrimeiros :: Eq => a -> [(a,b)] -> Bool 

instantiation này được nói rằng bây giờ, một có một kiểu mà có thể sánh ngang với và (e == x) sẽ không thất bại.

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