Là một newbie cho Haskell tôi đang cố gắng lặp lại một hàm (ví dụ, bản đồ hậu cần) một số lượng lớn lần. Trong một ngôn ngữ bắt buộc này sẽ là một vòng lặp đơn giản, tuy nhiên trong Haskell tôi kết thúc với tràn ngăn xếp. Lấy ví dụ mã này:Haskell: lặp lại một hàm số lần lớn mà không cần stackoverflow
main = print $ iter 1000000
f x = 4.0*x*(1.0-x)
iter :: Int -> Double
iter 0 = 0.3
iter n = f $ iter (n-1)
Đối với một số lượng nhỏ các lần lặp mã hoạt động, nhưng đối với một triệu lần lặp tôi nhận được một tràn ngăn xếp không gian:
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
Tôi không thể hiểu tại sao điều này xảy ra. Việc đệ quy đuôi nên được tốt ở đây. Có thể vấn đề là đánh giá lười biếng. Tôi đã thử nghiệm một số cách để đánh giá nghiêm ngặt, bằng cách chèn $!
hoặc seq
ở các vị trí khác nhau, nhưng không thành công.
Cách nào để Haskell lặp lại chức năng một số lượng lớn thời gian?
Tôi đã thử các đề xuất từ các bài đăng có liên quan: here hoặc here, nhưng tôi luôn kết thúc với luồng lưu lượng truy cập cho một số lượng lớn các lần lặp lại, ví dụ: main = print $ iterate f 0.3 !! 1000000
.
vấn đề là bạn không có đệ quy đuôi vì bạn không quay trở lại trực tiếp 'iter (n-1)' – Simon
Thật buồn cười khi mọi người không nhận được đệ quy đuôi là gì. FYI, định nghĩa này là sai: "khi tên của hàm chúng ta vừa xuất hiện trên dòng cuối cùng của hàm đó". – Ingo