Cách suy nghĩ về a `seq` b
không phải là nó "đánh giá a
" nhưng mà nó tạo ra một sự phụ thuộc giữa a
và b
, do đó khi bạn đi đến đánh giá b
bạn đánh giá a
là tốt.
Điều này có nghĩa là, ví dụ: a `seq` a
là hoàn toàn dư thừa: bạn đang yêu cầu Haskell đánh giá a
khi bạn đánh giá a
. Theo cùng một logic, seq a
chỉ với một đối số sẽ không khác biệt gì so với việc chỉ viết a
một mình.
Chỉ cần có seq a
bằng cách nào đó đánh giá a
sẽ không hoạt động. Vấn đề là seq a
chính nó là một biểu thức có thể không được đánh giá — nó có thể là sâu bên trong một số khối lồng nhau, ví dụ. Vì vậy, nó sẽ chỉ trở nên có liên quan khi bạn nhận được để đánh giá toàn bộ biểu thức seq a
- lúc này bạn sẽ tự mình đánh giá a
.
@ Ví dụ của Rhymoid về cách nó được sử dụng trong một nếp gấp nghiêm ngặt (foldl'
) là tốt. Mục tiêu của chúng tôi là viết một nếp gấp sao cho giá trị lũy kế trung gian của nó (acc
) được đánh giá hoàn toàn ở mỗi bước ngay sau khi chúng tôi đánh giá kết quả cuối cùng. Này được thực hiện bằng cách thêm một seq
lệch giữa giá trị tích lũy và cuộc gọi đệ quy:
foldl' f z (x:xs) =
let z' = f z x in z' `seq` foldl' f z' xs
Bạn có thể hình dung đây là một chuỗi dài của seq
giữa mỗi ứng dụng của f
trong nếp gấp, kết nối tất cả trong số họ để kết quả cuối cùng . Bằng cách này khi bạn đánh giá biểu thức cuối cùng (tức là số bạn nhận được bằng cách tổng hợp một danh sách), nó đánh giá các giá trị trung gian (tức là một phần tổng khi bạn gấp trong danh sách) một cách nghiêm ngặt.
Nguồn
2016-09-22 17:23:58
Nếu bạn nhìn vào định nghĩa [đã được định dạng rất kém) của 'foldl''] (https://wiki.haskell.org/Seq), bạn thấy rằng bạn thường chỉ muốn đánh giá nghiêm ngặt một số biến giới hạn trong 'a' mà bạn nạp vào giá trị' b' của bạn. –