2012-02-14 13 views
5

Sto lavorando al libro Real-World Functional Programming e ho cercato di trovare il mio esempio di ricorsione della coda prima di leggere l'esempio del libro (elenco 10.2, pagina 265). L'esempio del libro funziona; la mia causa uno stack overflow.Perché questa coda non è ricorsiva?

Ho trovato se utilizzo un argomento di tupla o pre-calcolare a + accum quindi il mio funzionerà. Voglio capire perché.

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 

risposta

10
sum2 b a + accum 

Si noti che questo viene analizzato come (sum2 b a) + accum, non sum2 b (a + accum).

Quindi chiama sum2 b a. Quindi prende il risultato di quella chiamata e aggiunge accum ad esso. Quindi l'ultima espressione valutata è l'aggiunta, non la chiamata a sum2. Pertanto la chiamata a sum2 non è una coda.

5

Forse il compilatore è la lettura

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

invece di

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

Aaargh! Tu e @ sepp2k siete chiari. È l'ordine di valutazione. Le parentesi la risolvono. – TrueWill

+3

Di solito sovrasascalizzo tutto, poiché ho scoperto che è il male minore. Yay comune lisp !!! – gpeche

Problemi correlati