निम्नलिखित blog article दिखाता है कि एफ # foldBack
में निरंतरता गुजर शैली का उपयोग पूंछ पुनरावर्ती बनाया जा सकता है।क्या फोल्ड राइट पूंछ रिकर्सिव बनाने के लिए निरंतरता का उपयोग करना संभव है?
स्काला में यह इसका मतलब यह होगा:
def foldBack[T,U](l: List[T], acc: U)(f: (T, U) => U): U = {
l match {
case x :: xs => f(x, foldBack(xs, acc)(f))
case Nil => acc
}
}
ऐसा करके पूंछ पुनरावर्ती बनाया जा सकता है:
def foldCont[T,U](list: List[T], acc: U)(f: (T, U) => U): U = {
@annotation.tailrec
def loop(l: List[T], k: (U) => U): U = {
l match {
case x :: xs => loop(xs, (racc => k(f(x, racc))))
case Nil => k(acc)
}
}
loop(list, u => u)
}
दुर्भाग्य से, मैं अभी भी लंबी सूची के लिए एक ढेर अतिप्रवाह मिलता है। लूप पूंछ रिकर्सिव और अनुकूलित है लेकिन मुझे लगता है कि स्टैक संचय केवल निरंतर कॉल में स्थानांतरित हो गया है।
क्यों एफ # के साथ एक समस्या नहीं है? और क्या इस के आसपास स्कैला के साथ काम करने का कोई तरीका है?
संपादित: यहाँ कुछ कोड है कि ढेर की गहराई पता चलता है:
def showDepth(s: Any) {
println(s.toString + ": " + (new Exception).getStackTrace.size)
}
def foldCont[T,U](list: List[T], acc: U)(f: (T, U) => U): U = {
@annotation.tailrec
def loop(l: List[T], k: (U) => U): U = {
showDepth("loop")
l match {
case x :: xs => loop(xs, (racc => { showDepth("k"); k(f(x, racc)) }))
case Nil => k(acc)
}
}
loop(list, u => u)
}
foldCont(List.fill(10)(1), 0)(_ + _)
यह प्रिंट:
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
loop: 50
k: 51
k: 52
k: 53
k: 54
k: 55
k: 56
k: 57
k: 58
k: 59
k: 60
res2: Int = 10
यह समझ में नहीं आता है। क्या आपके पास एक साधारण परीक्षण मामला है? –
@ डैनियल सी। सोब्राल, मैंने जो कोड जोड़ा है उसे देखें और यह प्रिंट करता है। – huynhjl