2011-06-25 19 views
6

स्कैला सीखने के अपने निरंतर प्रयास में, मैं ओडर्स्की द्वारा 'स्कैला उदाहरण के माध्यम से' और प्रथम श्रेणी के कार्यों के अध्याय पर काम कर रहा हूं, अज्ञात फ़ंक्शन पर अनुभाग रिकर्सिव अनाम फ़ंक्शन की स्थिति से बचाता है। मेरे पास एक समाधान है जो काम करता प्रतीत होता है। अगर वहां कोई बेहतर जवाब है तो मैं उत्सुक हूं।मैं रिकर्सिव अनाम फ़ंक्शन कैसे लिखूं?

पीडीएफ से: कोड उच्च आदेश कार्यों

def sum(f: Int => Int, a: Int, b: Int): Int = 
    if (a > b) 0 else f(a) + sum(f, a + 1, b) 

def id(x: Int): Int = x 
def square(x: Int): Int = x * x 
def powerOfTwo(x: Int): Int = if (x == 0) 1 else 2 * powerOfTwo(x-1) 

def sumInts(a: Int, b: Int): Int = sum(id, a, b) 
def sumSquares(a: Int, b: Int): Int = sum(square, a, b) 
def sumPowersOfTwo(a: Int, b: Int): Int = sum(powerOfTwo, a, b) 

scala> sumPowersOfTwo(2,3) 
res0: Int = 12 
पीडीएफ से

प्रदर्शन करने के लिए:

def sumPowersOfTwo(a: Int, b: Int): Int = sum((x: Int) => { 
    def f(y:Int):Int = if (y==0) 1 else 2 * f(y-1); f(x) }, a, b) 

scala> sumPowersOfTwo(2,3) 
res0: Int = 12 
+0

क्या आप इसके बारे में निश्चित हैं? 'echo "2^2 + 3^2" | बीसी -एल' -> '13'। – sarnold

+0

यह एक डुप्लिकेट है http://stackoverflow.com/questions/5337464/anonymous-recursive-function-in-scala – Suroot

+1

@ दो की शक्तियों के कर्नाल्ड योग - यानी '2^ए + 2^ए + 1 + ... 2^बी -1 + 2^बी' '2^2 + 2^3 = 4 + 8 = 12' –

उत्तर

13

के लिए: अनाम प्रक्रियाएं

def sum(f: Int => Int, a: Int, b: Int): Int = 
    if (a > b) 0 else f(a) + sum(f, a + 1, b) 

def sumInts(a: Int, b: Int): Int = sum((x: Int) => x, a, b) 
def sumSquares(a: Int, b: Int): Int = sum((x: Int) => x * x, a, b) 
// no sumPowersOfTwo 

मेरे कोड का प्रदर्शन करने के कोड यह क्या लायक है ... (शीर्षक और "असली सवाल" काफी नहीं है इस बात से सहमत)

रिकर्सिव गुमनाम समारोह वस्तुओं "लंबे हाथ" की FunctionN और फिर this(...) का उपयोग कर apply अंदर विस्तार के माध्यम से बनाया जा सकता है।

(new Function1[Int,Unit] { 
    def apply(x: Int) { 
    println("" + x) 
    if (x > 1) this(x - 1) 
    } 
})(10) 

हालांकि, आम तौर पर यह अनुमान लगाया जाता है कि आम तौर पर आदर्श आदर्श से दृष्टिकोण को कम करता है। बेस्ट सिर्फ एक "नाम" का उपयोग करें और कुछ और वर्णनात्मक, मॉड्यूलर कोड है - नहीं है कि इस तरह के निम्नलिखित ;-)

val printingCounter: (Int) => Unit = (x: Int) => { 
    println("" + x) 
    if (x > 1) printingCounter(x - 1) 
} 
printingCounter(10) 

मुबारक कोडिंग के लिए एक बहुत अच्छा तर्क है।

2

आप को यह अप्रत्यक्ष प्रत्यावर्तन सामान्यीकरण कर सकते हैं:

case class Rec[I, O](fn : (I => O, I) => O) extends (I => O) { 
    def apply(v : I) = fn(this, v) 
} 

अब राशि के रूप में अप्रत्यक्ष प्रत्यावर्तन का उपयोग कर लिखा जा सकता है:

val sum = Rec[Int, Int]((f, v) => if (v == 0) 0 else v + f(v - 1)) 

ही समाधान उदाहरण के लिए Memoization लागू करने के लिए इस्तेमाल किया जा सकता।

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