【问题标题】:Tracing recursive calls in OOP在 OOP 中跟踪递归调用
【发布时间】:2016-08-21 17:42:34
【问题描述】:

我对跟踪/理解 Javascript、Haskell 等函数式语言中的递归调用有些自在,最近我正在学习 Scala 课程,目前该课程严重依赖递归。

这是一个简单的例子:

abstract class IntSet {
  def incl(x: Int): IntSet
  def contains(x: Int): Boolean
  def union(other: IntSet): IntSet
}

class Empty extends IntSet {
  def contains(x: Int): Boolean = false
  def incl(x: Int): IntSet = new NonEmpty(x, new Empty, new Empty)
  def union(other: IntSet): IntSet = other
}

class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {
  def contains(x: Int): Boolean =
    if (x < elem) left contains x
    else if (x > elem) right contains x
    else true

  def incl(x: Int): IntSet =
   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(other: IntSet): IntSet =
   ((left union right) union other)incl(elem)
}

虽然直观上递归似乎可以理解,但我很难扩展一般情况,而 base case 感觉非常好。

((left union right) union other)incl(elem)

主要是因为左参考上下文在正常的函数式语言中不存在。在处理和理解这些递归调用时,我如何才能让自己感到舒适?

更新

根据我认为下面的答案将是扩展递归树的调用序列。

  1. incl(union(union(left, right), other), elem)
  2. incl(union(incl(union(union(left, right), other), elem), other), elem)

但我认为它很快就会变得太毛茸茸,是否有任何图片替代品或模态可以理解这一点?

【问题讨论】:

  • 您所说的“因为在普通函数式语言中没有左参考上下文。”是什么意思?什么是“普通”函数式语言,函数在那里看起来如何?
  • @Bergi 我的意思是通常我会做function foo(largerInstance) -&gt; function foo(smallerInstance) .... function foo(baseCase),即我的函数调用仅取决于参数,但在这里我看到函数取决于调用函数的对象。
  • 考虑一个对象,在该对象上调用函数作为始终存在的隐式参数(虽然并不总是使用,尤其是在 Scala 中)。喜欢incl(union(union(left, right), other), elem)。只有所有函数的第一个参数都是多态的。
  • @CodeYogi 将对象视为第一个参数,属性被隐式解构/模式匹配等。
  • @VictorMoroz 很棒,但你不认为扩展这个函数会是一项痛苦的任务吗?在考虑递归算法时,你觉得这个函数或对象引用的哪个符号更有帮助?

标签: scala oop recursion recursive-datastructures


【解决方案1】:

Union 在这里是一种很难理解的方法,这是真的。当我第一次看到它时,它似乎很奇怪,因为它似乎做的很少。它确实有助于绘制两棵小树并通过它进行追踪以了解整个事情是如何工作的,但本质上,它与任何其他递归没有什么不同。大部分工作由incl 完成,实际上是将每个元素添加到 int 集中,一次一个。 union 所做的就是一遍又一遍地递归地分解问题,直到你得到一个空的 int 集。然后一个接一个的 incl 方法将每个元素添加回集合中,将其构建为一个集合,该集合包括原始 int 集合和另一个 int 集合中的所有元素。

顺便说一句,奥德斯基的课程很棒。几个月前自己完成了。

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 2018-12-31
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多