Đó là một tuyên bố nghiêm ngặt. Về cơ bản, điều đó có nghĩa là nó phải được ước tính theo cái gọi là "dạng bình thường đầu yếu" khi giá trị cấu trúc dữ liệu được tạo. Hãy xem xét một ví dụ, để chúng ta có thể thấy điều này có nghĩa là gì:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
Hàm f
trên, khi được đánh giá, sẽ trả về một "thunk": đó là mã để thực thi để tìm ra giá trị của nó. Tại thời điểm đó, một Foo thậm chí chưa tồn tại, chỉ là mã.
Nhưng đến một lúc nào đó, ai đó có thể cố gắng nhìn vào bên trong nó, có thể thông qua một trận đấu mẫu:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Điều này sẽ thực thi đủ mã để làm những gì nó cần, và không còn nữa. Vì vậy, nó sẽ tạo ra một Foo với bốn tham số (vì bạn không thể nhìn vào bên trong mà không có nó). Đầu tiên, vì chúng tôi đang thử nghiệm nó, chúng tôi cần đánh giá tất cả các cách để 4
chúng tôi nhận ra nó không phù hợp.
Thứ hai không cần phải được đánh giá, bởi vì chúng tôi không kiểm tra nó. Do đó, thay vì 6
được lưu trữ ở vị trí bộ nhớ đó, chúng tôi sẽ chỉ lưu trữ mã để đánh giá sau này (3+3)
. Điều đó sẽ biến thành số 6 chỉ khi ai đó nhìn vào nó.
Tuy nhiên, tham số thứ ba có !
phía trước nó, do đó được đánh giá nghiêm ngặt: (4+4)
được thực thi và 8
được lưu trữ ở vị trí bộ nhớ đó.
Tham số thứ tư cũng được đánh giá nghiêm ngặt. Nhưng đây là nơi có một chút khó khăn: chúng tôi đang đánh giá không đầy đủ, mà chỉ ở dạng đầu yếu thông thường. Điều này có nghĩa là chúng tôi tìm ra liệu nó Nothing
hay Just
cái gì đó, và lưu trữ nó, nhưng chúng tôi không đi xa hơn. Điều đó có nghĩa là chúng tôi lưu trữ không Just 10
nhưng thực sự Just (5+5)
, để lại thunk bên trong không có giá trị. Điều này rất quan trọng để biết, mặc dù tôi nghĩ rằng tất cả các tác động của điều này đi ra ngoài phạm vi của câu hỏi này.
Bạn có thể chú thích các đối số hàm theo cùng một cách, nếu bạn bật BangPatterns
tiện ích mở rộng ngôn ngữ:
f x !y = x*y
f (1+1) (2+2)
sẽ trả lại thunk (1+1)*4
.