Сумма двоичного дерева с продолжениями с разделителями Scala

Я играю со Scala и начинаю с нескольких простых примеров, таких как реализация бинарных деревьев. Имея предварительные знания о функциональном программировании (OCaml, F#), я пытался повторить общий подход использования продолжений, чтобы сделать обход двоичного дерева хвостовым рекурсивным. Я читаю столько, сколько я могу о продолжениях Scala с разделителями, но я не смог заставить его работать.

Вы можете прочитать реализацию этого поведения в OCaml из этого вопроса Stackru

Я следовал примерам из этого " Введения в программирование с помощью Shift и Reset", но я всегда получаю ошибки типов и изменения, которые я вносил, чтобы попытаться заставить его работать, давал правильные результаты, но без рекурсивного хвоста функции.

Вот моя реализация

abstract class IntTree
case object EmptyTree extends IntTree
case class Node( value : Int, left : IntTree, right : IntTree) extends IntTree

abstract class Result
case object Done extends Result
case class Next( n:Int, f : ( Unit => Result ) ) extends Result

def Sum(tree: IntTree): Int = {
  def walk( t : IntTree) : Unit = t match {
    case EmptyTree => ()
    case Node(v, left, right) => {
      walk(left)
      reset {
        shift { k: (Unit => Result) => Next(v, k) }
        walk(right)
      }
    }
  }
  def start( t : IntTree) = { walk(t); Done }
  def sumResult( ls : Result, acc : Int) : Int = ls match {
    case Done => acc
    case Next(value, k) => {
      sumResult(k(), acc + value)
    }
  }


  sumResult( start(tree), 0 )
}

Мне также интересно, являются ли продолжения с разделителями правильными инструментами для этой работы. Я знаю, что эту проблему можно эффективно решить, передав явный стек, но я хотел бы понять, как использовать cps в Scala.

0 ответов

Другие вопросы по тегам