scala - Scala 2nd edition 问题中的 Queue3 第 19 章编程

标签 scala

我正在对 Odersky 等人的 Programming in Scala 2nd edition 中的 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 时,书中指出,由于前导为空,镜像将复制尾随的所有内容,将其反转并将其设置为前导。

问题是我认为这不起作用,因为它是一种方法?所以它不会通过状态持续存在。因为我公开了代码属性并检查了 q.leading 和 q.trailing 并且值是相同的。在我做 q.head 之后我期待的是:
q.leading is List(1,2) and q.trailing is List()

但事实并非如此,我错过了什么吗?这是我缺少的一些 FP 范式吗?因为我认为如果将 head 和 tail 方法更改为 var,它可以按照我认为应该工作的方式工作。

感谢您的时间。

编辑使属性公开:

私有(private) val 前导:List[T],
私有(private) val 尾随:List[T]

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

最佳答案

你的问题是 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()

关于scala - Scala 2nd edition 问题中的 Queue3 第 19 章编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7278772/

相关文章:

scala - Akka Http - 主机级客户端 API Source.queue 模式

scala - scala 规范 2.10 和 2.11 是否存在?

scala - 在 Scala Dispatch 0.9.5 中插入 Oauth header 的方法?

scala - 为什么 Scala 在 IntelliJ 中的大型 Java/Scala 项目上编译失败?

java - 什么是映射缓冲池/直接缓冲池以及如何增加它们的大小?

Scala 测试一个 Map 是双射的

scala - 如何从 Scala HList 中读取元素?

scala - 默认 AkkaSupport Servlet 示例不起作用

scala - 解析器组合信息

scala - 将未知长度的元组转换为 Scala 中的列表