Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 了解如何将递归转换为蹦床_Scala_Recursion_Tail Recursion_Trampolines - Fatal编程技术网

Scala 了解如何将递归转换为蹦床

Scala 了解如何将递归转换为蹦床,scala,recursion,tail-recursion,trampolines,Scala,Recursion,Tail Recursion,Trampolines,我最近读到关于蹦床是一种消除尾巴叫声的方法。我想将我的一个函数转换为使用蹦床的函数,但我现在很难开始(我来自OO世界) 具体来说,如果我想在“More()”语句中进行两个不同的递归调用,可以吗 您的buildTree方法不进行任何尾部调用,因此无法利用蹦床。当一个方法的返回值是另一个方法调用的结果时,尾部调用是一种优化。它允许堆栈帧替换为被调用函数的堆栈帧。如果没有尾部调用优化,递归函数调用将导致堆栈大小增加,可能导致堆栈溢出。buildTree方法确实调用了自身两次,但必须保留原始堆栈框架,以

我最近读到关于蹦床是一种消除尾巴叫声的方法。我想将我的一个函数转换为使用蹦床的函数,但我现在很难开始(我来自OO世界)


具体来说,如果我想在“More()”语句中进行两个不同的递归调用,可以吗

您的
buildTree
方法不进行任何尾部调用,因此无法利用蹦床。当一个方法的返回值是另一个方法调用的结果时,尾部调用是一种优化。它允许堆栈帧替换为被调用函数的堆栈帧。如果没有尾部调用优化,递归函数调用将导致堆栈大小增加,可能导致堆栈溢出。buildTree方法确实调用了自身两次,但必须保留原始堆栈框架,以便在创建新的
节点时可以组合两个函数调用的结果

JVM没有内置的对tail-all优化的支持,但是Scala有一个对函数自身调用的tail调用的攻击。Scala将这些递归函数调用替换为跳转到函数的开头,有效地将递归转化为迭代。不幸的是,这不适用于共递归调用(例如,当方法A调用B而B调用A时)。这里可以使用蹦床,或者基于特殊的monad,或者滥用异常处理。没有理由在其他地方使用蹦床

def buildTree (X:DenseMatrix[Double], Y:DenseVector[Double], minBucket:Int):Node = {
        // Get the split variable, split point and data for this data
        val (splitVar, splitPoint, leftX, leftY, rightX, rightY) = chooseSplit(X, Y, minBucket);
        // If we couldn't find a split, then we have a leaf
        if(splitVar == Double.NegativeInfinity){
            new Node(Y)
        }else{
            // Otherwise recursively build the children and create yourself as a vertex
            val left =  buildTree(leftX, leftY, minBucket))
            val right = buildTree(rightX, rightY, minBucket))
            new Node(Y, splitVar, splitPoint, left, right)
        }
    }