2012-02-14 17 views
5

मैं Real-World Functional Programming पुस्तक के माध्यम से काम कर रहा हूं, और मैंने किताब के उदाहरण पढ़ने से पहले पूंछ रिकर्सन के अपने उदाहरण के साथ आने की कोशिश की (लिस्टिंग 10.2, पृष्ठ 265)। पुस्तक का उदाहरण काम करता है; मेरा एक ढेर अतिप्रवाह का कारण बनता है।यह पूंछ-पुनरावर्ती क्यों नहीं है?

मुझे पता चला है कि मैं एक ट्यूपल तर्क का उपयोग करता हूं या a + accum की पूर्व-गणना करता हूं तो मेरा काम करेगा। मैं समझना चाहता हूं क्यों।

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 

उत्तर

10
sum2 b a + accum 

ध्यान दें कि यह (sum2 b a) + accum, नहीं sum2 b (a + accum) के रूप में पार्स किया जाता है।

तो यह sum2 b a पर कॉल करता है। फिर यह उस कॉल का परिणाम लेता है और इसमें accum जोड़ता है। तो मूल्यांकन की आखिरी अभिव्यक्ति अतिरिक्त है, sum2 पर कॉल नहीं। इस प्रकार sum2 पर कॉल पूंछ कॉल नहीं है।

5

शायद संकलक

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

Aaargh के बजाय

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

पढ़ रही है! आप और @ sepp2k स्पॉट-ऑन हैं। यह मूल्यांकन का आदेश है। कोष्ठक इसे ठीक करते हैं। – TrueWill

+3

मैं आमतौर पर सबकुछ खत्म कर देता हूं, जैसा कि मैंने पाया है कि यह कम बुराई है। हाँ आम lisp !!! – gpeche

संबंधित मुद्दे