Scala 什么使递归函数有限

Scala 什么使递归函数有限,scala,recursion,Scala,Recursion,我正在编写类来表示一组整数。我就是这样做的: abstract class IntSet { def incl(x: Int): IntSet def union(x: IntSet): IntSet def union1(x: IntSet): IntSet } class Empty extends IntSet { def incl(x: Int) = new NonEmpty(x, new Empty, new Empty) def union(x: IntS

我正在编写类来表示一组整数。我就是这样做的:

abstract class IntSet {
   def incl(x: Int): IntSet
   def union(x: IntSet): IntSet
   def union1(x: IntSet): IntSet
}

class Empty extends IntSet {
  def incl(x: Int) = new NonEmpty(x, new Empty, new Empty)
  def union(x: IntSet) = x
  def union1(x: IntSet) = x
}

class NonEmpty(var elem: Int, var left: IntSet, var right: IntSet)
extends IntSet {
   def incl(x: Int) = {
      if (x < elem) new NonEmpty(elem, left incl x, right)
      else if (x > elem) new NonEmpty(elem, left, right incl x)
      else this
   }
   def union(x: IntSet) = ((left union right) union x) incl elem
   def union1(x: IntSet) = ((left union1 x) union1 (right union1 x)) incl elem
}
并尝试对其调用union: 调用one.uniontwo可以正常工作,但one.union1two会导致StackOverflow异常。 我知道递归函数必须导致非递归定义的值是有限的。第一种情况下的union中的值是什么?为什么程序不能达到第二种情况下union1中定义的值?
一般的问题更多的是关于数学理论,而不是Scala,但是在编写递归函数以使其有限时,有没有什么技巧规则可以遵循呢?

您通常希望减少一个参数以获得一个基本参数 案例您的示例有点复杂,但union1实际上有两个 参数:x,就我们的目的而言,这可以被视为 参数基本情况是当它为空时,那么让我们看看 你可以在这上面减少

现在,对union1进行三次递归调用。让我们看两个更简单的例子 一个:左UNION1X和右UNION1X。在这些,你肯定是 在这上面。左和右必须小于此值,因为它们 不包括元素。这很好,你肯定会遇到这样的情况 这是空的

第三个,左union1 x union1右union1 x,是另一个故事。 因为它在左手边也包含了所有的x,所以没有 当this==x时,此值减小。例如,考虑采取的情况 简单集与自身的并。让\/表示union1和+表示 下面是代码计算{1}\/{1}的基本概念:

{1} \/ {1}
(({} \/ {1}) \/ ({} \/ {1})) + 1
({1} \/ {1}) + 1
...
我们现在需要再次计算{1}\/{1},所以我们将无限重复这个过程

因此,一般来说,请确保至少有一个参数具有基础 这种情况正在减少。要完全避免堆栈溢出,还应使用 尾部递归,用于处理非常大的
设置,或找到一种使用现有高阶函数而不是递归的方法。

您的问题不清楚,您还没有提供一个解决方案。请参见。一旦你用必要的细节更新了你的问题,你可能会得到一些合理的答案。@SergGr看起来这个问题已经被打捞上来了。非常感谢。我现在可以看到,每个示例输入都会在某个点上导致x\/x。
{1} \/ {1}
(({} \/ {1}) \/ ({} \/ {1})) + 1
({1} \/ {1}) + 1
...