2012-02-14 17 views
5

Real-World Functional Programming numaralı kitapta çalışıyorum ve kitabın örneğini okumadan önce kendi kuyruğumu özüme getirmeye çalıştım (listeleme 10.2, s. 265). Kitabın örnek çalışmaları; benimki bir yığın taşmasına neden oluyor.Bu kuyruk neden yinelenmiyor?

Bir tuple argümanı veya a + accum ön hesaplamasını kullanıp kullanmadığımı buldum, sonra benimki işe yarayacak. Nedenini anlamak istiyorum. Bu (sum2 b a) + accum değil sum2 b (a + accum) olarak ayrıştırılır olduğunu

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 

cevap

10
sum2 b a + accum 

Not.

Bu, sum2 b a numaralı telefonu arar. Sonra bu aramanın sonucunu alır ve buna accum ekler. Sonuç olarak değerlendirilen son ifade, sum2 numaralı çağrı değil, ekleme işlemidir. Böylece sum2 numaralı çağrı bir kuyruk çağrısı değildir.

5

Belki derleyici

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

Aaargh yerine

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

okuyor! Siz ve @ sepp2k sizsiniz. Değerlendirme sırası. Parantez bunu düzeltir. – TrueWill

+3

Genellikle herşeyi parantez içinde bırakıyorum, daha az kötülük olduğunu keşfettim. Yay ortak lisp !!! – gpeche