2013-06-03 24 views
8

tôi đã có thể thực thi mã sau hoàn hảoKhông thể phù hợp với loại dự kiến ​​'một 'với kiểu thực tế `[a]'

myLast :: [a] -> a 
myLast [] = error "Can't call myLast on an empty list!" 
myLast (x:_) = x 

nhưng tôi nhận được lỗi này Couldn't match expected type `a' with actual type `[a]'. `a' is a rigid type variable bound by the type signature for myLast :: [a] -> a cho đoạn mã sau:

myLast :: [a] -> a 
myLast [] = error "Can't call myLast on an empty list!" 
myLast (_:x) = x 

Tôi là người mới bắt đầu trong Haskell và thông báo lỗi là quá Hy Lạp và Latinh đối với tôi. Từ những gì tôi có thể hiểu, trình biên dịch không thể suy ra loại trong trường hợp thứ hai. Ai đó có thể chỉ cho tôi những gì đang thực sự xảy ra ở đây không?

Trả lời

13

Bạn tuyên bố đầu vào là danh sách loại [a] và phần còn lại thuộc loại a.

Danh sách loại a trong Haskell bao gồm một đầu loại a và đuôi, danh sách loại [a]. Hàm tạo đối tượng : lấy đầu và đuôi làm đối số của nó.

Khi bạn xây dựng danh sách là (x:y), x là đầu và y là đuôi. Vì vậy, trong đoạn mã thứ hai của bạn, bạn đang ràng buộc đuôi của danh sách, có loại danh sách [a], khi chữ ký loại của bạn yêu cầu bạn trả lại giá trị loại a (đầu là một ví dụ).

2

(_:x) khớp _ với đầu và x với đuôi của danh sách. Loại đuôi của danh sách là [a]. Bạn đang cố gắng trả về [a] 'khi khai báo hàm xác định kiểu trả về là a.

myLast (_:x) = x 

Nếu bạn muốn kết hợp yếu tố cuối cùng hãy xem câu trả lời này - Can you use pattern matching to bind the last element of a list?

6

Có sự hiểu biết về những gì : thực sự là sẽ giúp giải mã các thông báo lỗi. : có thể được coi như là một chức năng mà phải mất một phần tử và một danh sách, và trả về một danh sách đó có yếu tố đầu tiên là đối số đầu tiên và phần còn lại của nó là đối số thứ hai, hoặc:

(:) :: a -> [a] -> [a] 

Đến của bạn chức năng, bạn đã viết myLast :: [a] -> a; tuy nhiên, loại myLast (_:x) = xmyLast :: [a] -> [a] vì đối số thứ hai của : (mà bạn đặt tên là x) chính là danh sách.

Ngoài ra, nói chung khi bạn không hiểu điều gì đó trong Haskell, bạn nên xem xét loại đầu tiên sử dụng :t trong GHCI.

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