Việc thực hiện kinh điển của length :: [a] -> Int
là:Làm cách nào để viết hàm chiều dài không gian cố định trong Haskell?
length [] = 0
length (x:xs) = 1 + length xs
mà là rất đẹp nhưng bị chồng tràn vì nó sử dụng không gian tuyến tính.
Phiên bản đuôi-đệ quy:
length xs = length' xs 0
where length' [] n = n
length' (x:xs) n = length xs (n + 1)
không bị vấn đề này, nhưng tôi không hiểu làm thế nào điều này có thể chạy trong không gian liên tục trong một ngôn ngữ lười biếng.
Không phải thời gian chạy tích lũy nhiều số (n + 1)
khi di chuyển qua danh sách? Không nên chức năng này Haskell để tiêu thụ không gian O (n) và dẫn đến tràn ngăn xếp?
(nếu vấn đề, tôi đang sử dụng GHC)
Mã của người hỏi thực sự tràn ngăn xếp. Nói chung, trong đệ quy đuôi Haskell không ** không ** làm những gì bạn mong đợi nó để làm, và chức năng đệ quy đuôi lười biếng thường là lỗi. Xem ở đây: http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl 'Quy tắc ngón tay cái: hoặc làm cho nó nghiêm ngặt như 'foldl'', hoặc làm cho nó recurse thành một constructor như' foldr'. –
Ôi, quả hạch. Đánh dấu không giống như dấu nháy đơn ở cuối một URL, rõ ràng. Hãy thử lại: http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl%27 –