Nó không được biết đến rộng rãi, nhưng foldl'
thực sự không nghiêm ngặt trong đối số tích lũy của nó! Nhớ lại những loại:
foldl' :: (a -> b -> a) -> a -> [b] -> a
nghiêm minh của nó trong lập luận 2 phụ thuộc vào tính nghiêm minh của hàm trao cho lập luận 1, như bạn thấy nếu bạn vượt qua const
:
Prelude Data.List> foldl' (const (+1)) undefined [1]
2
Prelude Data.List> foldl' (const (+1)) undefined [1..4]
5
Bạn sẽ phải suy nghĩ, ngây thơ, rằng "foldl" là nghiêm ngặt "có nghĩa là" nghiêm ngặt trong các đối số accumulator ". Những mâu thuẫn trên.
Tuy nhiên, nó thậm chí còn xảo quyệt hơn, vì mức độ nghiêm ngặt chỉ là kết quả của ứng dụng chức năng trong trường hợp khuyết điểm của vòng lặp. Vì vậy, bạn vẫn nhận được đáy nếu bạn nhập trường hợp cơ sở, nhưng không phải là trường hợp quy nạp:
Prelude Data.List> foldl' (const (+1)) undefined []
*** Exception: Prelude.undefined
Vì vậy, sự nghiêm khắc in argument 2cũng phụ thuộc vào giá trị lập luận 3!
Đây là cách tôi viết nó: "hoàn toàn" nghiêm ngặt trong đối số thứ 2 của nó.
foldl' f z0 xs0 = go z0 xs0
where
go !z [] = z
go !z (x:xs) = go (f z x) xs
Đó là thực sự nghiêm ngặt trong số thứ hai của nó, như bạn có thể thấy:
Prelude Data.List.Stream> foldl' (\a b -> 1) undefined [undefined]
*** Exception: Prelude.undefined
So với phiên bản Haskell2010:
Prelude Data.List.Stream> Data.List.foldl' (\a b -> 1) undefined [undefined]
1
actuall này có một tác động thực tế - các định nghĩa hiện tại sẽ không unbox đối số tích lũy của nó một cách nhất quán.
Lưu ý lịch sử: điều này được phát hiện khi chúng tôi xác định ngữ nghĩa nghiêm ngặt của thư viện danh sách cho giấy kết hợp luồng trong năm 2007 và cách tiếp cận để xác định độ chặt được đưa ra trong số PhD thesis của Duncan Coutt.
So sánh mã nguồn cho hai phiên bản nếp gấp và bạn có thể khai sáng. – augustss
@augustss có thể, bạn có thể trả lời câu hỏi này không? – jackalope
Như bạn có thể thấy, foldl 'tính toán đối số đầu tiên để lgo trước khi cuộc gọi, trong khi foldl sẽ (nói chung) vượt qua một thunk sẽ được đánh giá khi cần thiết. – augustss