2011-11-13 16 views
5

Vì vậy, tôi nhận ra đây là một bản sao có thể câu hỏi, vì có một số lỗi được báo cáo trên Stack Overflow, nhưng không có giải pháp nào có vẻ áp dụng cho vấn đề của tôi.Haskell, Mặc dù loại của tôi không được chỉ định Tôi nhận được lỗi này: Không thể khớp loại `a 'với` [a]', `a 'là biến kiểu cứng nhắc bị ràng buộc bởi

Vì vậy, tôi có chức năng sau:

elementAt' :: Integral b => [a] -> b -> a 
elementAt' [x:_] 1 = x 
elementAt' [x:xs] y = elementAt' xs yminus1 
    where yminus1 = y - 1 

Trong trường hợp bạn đang tự hỏi nó là vấn đề của 3 từ 99 Haskell Problems. Mục tiêu của hàm là lấy đầu vào một danh sách và một chỉ mục, và trả về giá trị tại chỉ mục đó (bắt đầu từ 1). Tôi không muốn một giải pháp cho vấn đề, nếu tôi đã làm tôi chỉ có thể nhìn vào những người được cung cấp. Nhưng tôi nhận được một lỗi mà tôi không hiểu. Tôi đang sử dụng eclipseFP, plugin nhật thực cho Haskell và nó nhấn mạnh "[x: _]" và "[x: xs]" phần của chức năng với các lỗi sau:

Couldn't match type `a' with `[a]' 
`a' is a rigid type variable bound by 
the type signature for elementAt' :: Integral b => [a] -> b -> a 

Trong tất cả các chủ đề thảo luận về lỗi này mà tôi đã xem xét vấn đề thường xảy ra khi ai đó cố gắng đưa ra một kết quả không chính xác cho cái gì đó mong đợi một loại nhất định. Ví dụ, trả về độ dài của một cái gì đó (có kiểu Int) cho loại biến thể "Num a".

Nhưng trong trường hợp của tôi, tôi thậm chí không cung cấp loại cho biến a. Nó sẽ có thể được bất cứ điều gì, phải không? Vậy tại sao tôi nhận được lỗi này? Nếu tôi hiểu tại sao tôi lại gặp lỗi, tôi có thể sửa nó, nhưng tôi không hiểu.

Ai đó có thể giải thích cho tôi lý do tôi nhận được lỗi này?

Trợ giúp của bạn được đánh giá cao, cảm ơn bạn. -Asaf

Chỉnh sửa: Mọi câu trả lời được cung cấp cho đến thời điểm này đều chính xác, cảm ơn tất cả vì thông tin hữu ích. Tôi sẽ chọn cái mà tôi tin là rõ ràng nhất (tôi phải đợi 5 phút để làm điều đó).

+0

lý do tại sao không chỉ viết '' elementAt '[x: xs] y = elementAt' xs (y-1) '' –

+0

@Vixen Điều đó khác với những gì tôi viết ... ngoài việc bao gồm khai báo biến? Rõ ràng trình biên dịch sẽ kết thúc làm điều tương tự chính xác trong cả hai trường hợp (sửa tôi nếu tôi sai). – Asaf

+0

Vâng, nó giống nhau, tôi chỉ nghĩ rằng có vẻ lạ khi tuyên bố một cái gì đó như yminus1, khi y-1 đọc dễ dàng hơn và trông đẹp hơn theo quan điểm của tôi –

Trả lời

3

Nếu bạn muốn phù hợp với danh sách lên đầu và đuôi, bạn nên sử dụng

elementAt' (x:_) 1 = x 

Vì vậy, cuối cùng

elementAt' :: Integral b => [a] -> b -> a 
elementAt' (x:_) 1 = x 
elementAt' (x:xs) y = elementAt' xs yminus1 
    where yminus1 = y - 1 

λ> elementAt' [1,2,3] 2 
2 

Có những gì bạn cần?

1

Sử dụng dấu ngoặc đơn, không dấu ngoặc: (x:xs)

module Aaa where 

elementAt' (x:_) 1 = x 
elementAt' (x:xs) y = elementAt' xs yminus1 
    where yminus1 = y - 1 
+0

Mặc dù bạn hiểu giải pháp, người hỏi có thể không - bạn đã không giải quyết 'ai đó có thể vui lòng giải thích cho tôi lý do tại sao tôi nhận được lỗi này?' –

+0

@ delnan đưa ra một lời giải thích ở trên. Nói chung tôi cố đưa ra câu trả lời chi tiết hơn. – nponeccop

9

Bước vào định nghĩa của bạn mà không cần khai báo kiểu cho thấy rằng loại suy ra là Integral b => [[a]] -> b -> a. Đúng vậy, các mẫu hiện tại của bạn khớp với danh sách các danh sách.

Mẫu như thế

f [pat] = ... 

phù hợp với một danh sách singleton có yếu tố duy nhất phù hợp với pat. Bạn muốn làm việc với cons aka (:) thay vì requring một độ dài nhất định, và sau đó bạn cần ngoặc thay vì dấu ngoặc:

elementAt' (x:xs) n = ... 

Các lỗi cơ bản nói "bạn đối xử với a (các yếu tố của đối số đầu tiên) như thể nó là một danh sách ".

+1

+1 để giải thích nguyên nhân của vấn đề, không chỉ làm cho các lỗi biến mất. –

3

But in my case I'm not even providing a type for variable a. It should be able to be ANYTHING, right?

Nó có thể là bất kỳ thứ gì. Theo loại chữ ký của bạn, người dùng chức năng của bạn có thể gọi chức năng của bạn với aInt, với a[Char] hoặc với `a 'là bất kỳ điều gì khác mà người dùng muốn.

Tuy nhiên, thông báo lỗi cho bạn biết rằng bạn đã xác định chức năng của mình để chỉ có thể gọi nó bằng a là danh sách thứ gì đó. I E. bạn đã định nghĩa nó, để đối số đầu tiên phải là một danh sách các danh sách - nó không thể là một danh sách của bất kỳ thứ gì khác. Và điều đó mâu thuẫn với chữ ký của bạn.

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