队列3第19章Scala编程第2版问题

时间:2011-09-02 02:41:59

标签: scala

我正在为Odersky等编写的Scala第2版编程中的Queue3示例进行代码审查。而且我猜我被卡住了。

这是代码: http://booksites.artima.com/programming_in_scala_2ed/examples/type-parameterization/Queues3.scala

object Queues3 {
  class Queue[T](
    private val leading: List[T], 
    private val trailing: List[T] 
  ) {
    private def mirror = 
      if (leading.isEmpty)
        new Queue(trailing.reverse, Nil)
      else
        this

    def head = mirror.leading.head

    def tail = { 
      val q = mirror 
      new Queue(q.leading.tail, q.trailing) 
    }

    def enqueue(x: T) = 
      new Queue(leading, x :: trailing)
    override def toString = 
      leading ::: trailing.reverse mkString ("Queue(", ", ", ")")
  }

  object Queue {
    // constructs a queue with initial elements `xs'
    def apply[T](xs: T*) = new Queue[T](xs.toList, Nil)
  }

  def main(args: Array[String]) {
    val q = Queue[Int]() enqueue 1 enqueue 2
    println(q)
  }
}

因此,它试图以函数式编程方式实现队列,速度类似于命令式方式。

所以要做到这一点,它会将队列分成两部分,这样我们就能以恒定速度追加到最后。整个队列基本上是:

leading ::: trailing.reverse

这本书说最糟糕的情况是领先是空的。

所以,如果代码执行此操作

val q = Queue[Int]() enqueue 1 enqueue 2

然后, q.leading是List(),q.trailing是List(2,1)

所以,当我打电话给q.head时,书中说由于领先是空的,镜像会将所有内容从尾随复制,反转并将其设置为领先。

问题是我认为这不起作用,因为它是一种方法?所以它不会通过国家持续存在。因为我将代码属性设置为public并检查了q.leading和q.trailing,并且值是相同的。我做q.head之后我所期待的是:

q.leading is List(1,2) and q.trailing is List()

但事实并非如此,我错过了什么吗?这是我错过的一些FP范式吗?因为我认为它可以按照我认为如果头和尾方法改变为var的方式工作。

感谢您的时间。

编辑公开属性:

private val leading:List [T], private val trailing:List [T]

编辑: 第1章第19章: http://www.artima.com/pins1ed/type-parameterization.html

1 个答案:

答案 0 :(得分:5)

您的问题是,headtail方法不会返回新的Queue。而你正在检查旧的。查看此版本的headtail。现在,他们在元组中返回新的Queue

def head: (T, Queue[T]) = {
    val q = mirror
    (q.leading.head, q)
  }

def tail: (Queue[T], Queue[T]) = {
  val q = mirror
  (new Queue(q.leading.tail, q.trailing), q)
}

如您所见,mirror工作正常。

val q = Queue[Int]() enqueue 1 enqueue 2
println(q)
printLT(q)
val q1 = q.head
println(q1._1)
printLT(q1._2)

def printLT[A](q: Queue[A]) {
  println("leading: " + q.leading)
  println("trailing: " + q.trailing)
}

输出:

Queue(1, 2)
leading: List()
trailing: List(2, 1)
1
leading: List(1, 2)
trailing: List()