2009-05-23 16 views
7

इस उदाहरण कोड ले लो (उपेक्षा यह पल के लिए बुरी तरह अक्षम किया जा रहा है)रिकर्सिव lambdas

let listToString (lst:list<'a>) = ;;' prettify fix 

    let rec inner (lst:list<'a>) buffer = ;;' prettify fix 
     match List.length lst with 
     | 0 -> buffer 
     | _ -> inner (List.tl lst) (buffer + ((List.hd lst).ToString())) 

    inner lst "" 

यह एक आम पैटर्न मैं एफ # में भर आते है, मैं एक आंतरिक समारोह जो खुद recurses की आवश्यकता है कुछ मूल्यों पर - और मुझे केवल एक बार इस समारोह की आवश्यकता है, क्या किसी भी तरह से लैम्ब्डा को स्वयं से (कुछ जादू कीवर्ड या कुछ) कहने के लिए संभव है? मैं कुछ इस तरह देखने के लिए कोड चाहते हैं:

let listToString2 (lst:list<'a>) = ;;' prettify fix 

    (fun 
     (lst:list<'a>) buffer -> match List.length lst with ;;' prettify fix 
           | 0 -> buffer 
           | _ -> ##RECURSE## (List.tl lst) (buffer + ((List.hd lst).ToString())) 
    ) lst "" 

लेकिन जैसा कि आप उम्मीद कर सकते हैं कोई रास्ता नहीं है के भीतर ही गुमनाम समारोह है, जो है जहाँ मैं ## recurse ##

उत्तर

17
डाल की जरूरत है का उल्लेख करने के है

हां, यह संभव है y-combinators (या fixed-point combinators) का उपयोग करना संभव है। उदाहरण के लिए:

let rec fix f x = f (fix f) x 

let fact f = function 
| 0 -> 1 
| x -> x * f (x-1) 


let _ = (fix fact) 5 (* evaluates to "120" *) 

मैं एफ # के लिए लेख पता नहीं है, लेकिन इस haskell entry भी उपयोगी हो सकता है।

लेकिन: अगर कोई विकल्प नहीं है मैं उन्हें का उपयोग नहीं होगा - वे बहुत समझना कठिन हो।

आपका कोड (यहाँ प्रकार एनोटेशन को छोड़ देते हैं) एक मानक निर्माण और भी बहुत कुछ अर्थपूर्ण है।

let listToString lst = 

    let rec loop acc = function 
     | [] -> acc 
     | x::xs -> loop (acc^(string x)) xs 

    loop "" lst 
1

ध्यान दें कि आप कहते हैं, हालांकि आप केवल एक बार समारोह का उपयोग तकनीकी रूप से आप दो बार नाम से यह उल्लेख करने के लिए है, जिसके कारण यह समझ में आता है कि यह एक नाम देने के लिए।

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