2009-07-29 50 views
7

Tôi đang cố gắng tự dạy mình Haskell. Một điều tôi đã cố gắng làm là viết một hàm thay thế để trả về phần tử cuối cùng của danh sách bằng cách đệ quy qua danh sách cho đến khi đuôi là tập rỗng và sau đó trả về phần đầu. Tôi có ...Thực hiện chức năng cuối cùng

mylast [] = [] 
mylast (x:[]) = x 
mylast (x:xs) = mylast xs 

... nhưng tôi nhận được một lỗi khi tôi thử bất kỳ danh sách không có sản phẩm nào :( Bất kỳ lời đề nghị như những gì tôi đã làm sai? TIA.

+1

Bạn nên chấp nhận câu trả lời rtperson ... – yeyeyerman

Trả lời

8

Hãy thử mylast [] = error "Empty list!" . Nếu không thay Haskell không thể suy ra các loại chức năng của bạn

6

giải pháp Efraim của nên làm việc (up-bình chọn) Nhưng tôi nghĩ rằng đây là nhiều hơn một chút "Haskell-like":..

mylast [] = Nothing 
mylast (x:[]) = Just x 
mylast (x:xs) = mylast xs 

Tuyên bố miễn trừ trách nhiệm: Tôi chưa thực sự thử điều này. Tôi có thể đã mắc lỗi cú pháp.

+2

Trường hợp giữa là giống như [ x], phải không? IOW, danh sách phần tử được tạo bằng cách nối x với danh sách rỗng "(x: [])" giống với danh sách chứa x "[x]". Tôi không biết cái nào là thành ngữ hơn. –

+0

Không, chỉ x không giống với [x]. –

+0

Ồ, chờ đã, tôi hiểu ý của bạn là gì. Có, trường hợp ở giữa là danh sách chỉ chứa một x. Nhưng tất cả các danh sách có thể được biểu thị dưới dạng đầu và đuôi, ngay cả khi một hoặc cả hai đều trống. –

29

Vấn đề - giống như nhiều người khác khi bạn đang học Haskell - là một trong những cách gõ. Gõ như sau vào GHCi

:t mylast 

và bạn sẽ thấy rằng chữ ký kiểu là

mylast :: [[a]] -> [a] 

mà hy vọng một danh sách liệt kê và sẽ trả về một danh sách. Vì vậy, nếu bạn đặt trong một danh sách các chuỗi ["bob", "hàng rào", "nhà"] chức năng sẽ hoạt động như bạn đã viết nó.

Vấn đề là trường hợp cơ sở của bạn: mylast [] = [], cho trình biên dịch biết bạn muốn trả về một danh sách. Bạn muốn trả lại một phần tử, không phải danh sách. Nhưng không có phần tử rỗng trong Haskell (rất nhiều theo thiết kế), vì vậy bạn cần phải sử dụng đơn nguyên Có lẽ.

mylast :: [a] -> Maybe a 
mylast [] = Nothing 
mylast (x:[]) = Just x 
mylast (x:xs) = mylast xs 

Monads là một chủ đề khá trừu tượng, nhưng bạn cần có thể là đơn nguyên khi bạn bắt đầu. Tất cả những gì bạn cần biết về nó là nó là một kiểu khai báo để cho trình biên dịch mong đợi hai khả năng: "Không có gì" hoặc "Chỉ x". Mã trả về có thể lấy x và chạy với nó, nhưng nếu bạn bỏ qua "Chỉ", trình biên dịch sẽ phàn nàn.

Cách khác là để ném ra một lỗi khi một danh sách trống đang gặp phải, như vậy:

mynextlast [] = error "no empty lists allowed" 
mynextlast (x:[]) = x 
mynextlast (x:xs) = mynextlast xs 

Nhưng sự nghi ngờ của tôi là Có lẽ là con đường để đi.

+6

một bài học từ điều này là nó rất hữu ích để xác định các loại công cụ bạn xác định. nó sẽ làm cho các lỗi bắt biên dịch như thế này .. – yairchu

+0

Cảm ơn bạn đã trả lời tất cả mọi người. Tôi đã cố gắng ... mylast3 :: [a] -> Có lẽ một mylast3 [] = Nothing mylast3 (x: []) = Chỉ cần x mylast3 (x: xs) = mylast3 xs và tôi nhận được ví dụ ... Main> mylast3 [2,4,66,5,4,33] Chỉ 33: Có thể là số nguyên Có cách nào để làm cho nó không in 'chỉ'? – user147056

+0

Cảm ơn bạn đã trả lời tất cả mọi người. Tôi đã cố gắng ... mylast3 :: [a] -> Có lẽ một mylast3 [] = Nothing mylast3 (x: []) = Chỉ cần x mylast3 (x: xs) = mylast3 xs và tôi nhận ví dụ ... Main> mylast3 [2,4,66,5,4,33] Chỉ 33: Có thể là số nguyên Có cách nào để làm cho nó không in 'chỉ'? – user147056

0

Cảm ơn bạn đã trả lời tất cả mọi người. Tôi đã cố gắng ...

mylast :: [a] -> Maybe a 
mylast [] = Nothing 
mylast (x:[]) = Just x 
mylast (x:xs) = mylast xs 

và tôi nhận được ví dụ như ...

Main> mylast3 [2,4,66,5,4,33] 
Just 33 :: Maybe Integer 

Liệu có cách nào làm cho nó không in 'chỉ' trong câu trả lời?

[CHỈNH SỬA: Jörg W Mittag] (Nhận xét rất tệ khi đăng mã ...)

Sau đây là cách toàn bộ mã trông trong bối cảnh:

mylast []  = Nothing 
mylast [x] = Just x 
mylast (x:xs) = mylast xs 

mylook (Just a) = do print a 
mylook Nothing = do error "Nothing to see here, move along!" 

mylook $ mylast [2,4,66,5,4,33] 
+2

Điểm của Có lẽ Monad (và những gì phân biệt nó từ, con trỏ NULL trong C hoặc null tham chiếu trong Java), là chữ ký loại rõ ràng buộc bạn phải đối phó với cả hai trường hợp: một cái gì đó đã được trả lại và không có gì được trả về . Vì vậy, bạn sẽ phải mô hình rõ ràng khớp trên cả hai trường hợp và đối phó với chúng một cách riêng biệt. Ví dụ. nếu bạn muốn in kết quả: mylook (Just a) = do in a! NEWLINE! mylook Nothing = do error "Không có gì để xem ở đây, di chuyển cùng!" !DÒNG MỚI! mylook $ mylast [2,4,66,5,4,33] –

+0

'x <- mylast3 [2, 4, 66, 5, 4, 33]' – rampion

+0

làm thế nào về "fromJust $ mylast [2,4,66, 5,4,33] "? (fromJust được nhập từ Data.Maybe) – newacct

0
myLast' [] = error "no empty lists allowed" 
myLast' [a] = a 
myLast' xs = xs !! (length xs - 1) 
+0

Thêm ngữ cảnh vào câu trả lời của bạn để giải thích những gì nó đang làm. – Adam

0
mylast [x] = x 
mylast (x:xs) = mylast xs 

đệ quy giải pháp gọi

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