2012-02-14 50 views
5

Tôi đang làm việc qua cuốn sách Real-World Functional Programming và tôi đã cố gắng đưa ra ví dụ về việc đệ quy đuôi của riêng tôi trước khi đọc ví dụ của sách (liệt kê 10.2, trang 265). Ví dụ của cuốn sách hoạt động; mỏ gây ra tràn ngăn xếp.Tại sao đuôi này không đệ quy?

Tôi đã tìm thấy nếu tôi sử dụng đối số tuple hoặc tính trước a + accum thì sẽ hoạt động. Tôi muốn hiểu tại sao.

let rnd = new System.Random() 
let test2 = List.init 1000000 (fun _ -> rnd.Next(-50, 51)) 

let rec sum2 list accum = 
    match list with 
    | [] -> accum 
    | a::b -> sum2 b a + accum 

let result = sum2 test2 0 

printfn "%d" result 

Trả lời

10
sum2 b a + accum 

Lưu ý rằng đây là phân tích cú pháp như (sum2 b a) + accum, không sum2 b (a + accum).

Vì vậy, điều này gọi sum2 b a. Sau đó, kết quả của cuộc gọi đó và thêm accum vào cuộc gọi đó. Vì vậy, biểu thức cuối cùng được đánh giá là bổ sung, không phải là cuộc gọi đến sum2. Do đó cuộc gọi đến sum2 không phải là cuộc gọi đuôi.

5

lẽ trình biên dịch được đọc

a::b -> (sum2 b a) + accum 

thay vì

a::b -> sum2 b (a + accum) 
+0

aaargh! Bạn và @ sepp2k được phát hiện tại chỗ. Đó là thứ tự đánh giá. Các dấu ngoặc đơn sửa chữa nó. – TrueWill

+3

Tôi thường over-parenthesize tất cả mọi thứ, như tôi đã tìm thấy nó là cái ác ít hơn. Yay phổ biến lisp !!! – gpeche

Các vấn đề liên quan