Có một số ma thuật trong loại hình lười biếng. Tôi nghĩ dễ hiểu hơn khi bạn tự mình thực hiện nó, điều này rất dễ dàng dù không thuận tiện về mặt cú pháp. Các thủ đoạn là
- chậm trễ đánh giá sử dụng đóng cửa
- tế bào sử dụng ref để memoize tính
đây thì rõ ràng như thế nào và khi memoization xảy ra trong Lazy'.force.
module Lazy' : sig
type 'a t
val delay: (unit -> 'a) -> 'a t
val force: 'a t -> 'a
end = struct
type 'a susp =
| NotYet of (unit -> 'a)
| Done of 'a
type 'a t = 'a susp ref
let delay f = ref (NotYet f)
let force f =
match !f with
| Done x -> x
| NotYet f' ->
let a = f'() in
f := Done a;
a
end
nhập 'a stream = Cons of' a * 'a Lazy'.t ;;
let ones = let rec ones '() = Cons (1, Lazy'.delay ones') trong ones '() ;;
let rec map f s = match s với | Nhược điểm (h, t) -> Nhược điểm (f h, Lazy'.delay (fun() -> map f (Lazy'.force t))) ;;
Mục đích của lần gián đoạn thứ hai tại 'type' a t = unit -> 'a susp ref' là gì? Bạn chỉ bao giờ quay trở lại 'fun() -> r' hoặc áp dụng' 'let s = f() in'. Tại sao bạn không thể cắt trung gian? PS: để được rõ ràng, tôi hỏi tại sao http://ideone.com/Eidm34 sẽ không hoạt động. –
Đồng ý. Nó không cần thiết. Chúng ta nên gõ ''a t =' a susp ref'. Các indirection là vestigial từ một nỗ lực trước đó :) – seanmcl