如何在 Scala 中创建不可变的双向链表?

How to create immutable Doubly LinkedList in Scala?

有人可以通过展示一种方法实现来帮助我在 Scala 中创建不可变双向链表吗?另外,您能否通过让我们实施 prepend(element:Int): DoublyLinkedList[Int] ?

来向我提供其中一个示例

Call By Name & lazy val(按需调用)使得拥有不可变的双向链表成为可能。

用 link 对已经 link 编辑的视频补充文本版本并包括重要引述:

这在 Immutable Doubly Linked Lists in Scala with Call-By-Name and Lazy Values

中有描述

A doubly-linked list doesn’t offer too much benefit in Scala, quite the contrary.

So this data structure is pretty useless from a practical standpoint, which is why ... there is no doubly-linked list in the Scala standard collection library

All that said, a doubly-linked list is an excellent exercise on the mental model of immutable data structures.

Think about it: this operation in Java would have been done in 3 steps:

  • new node
  • new node’s prev is 1
  • 1’s next is the new node

If we can execute that new 1 ⇆ 2 in the same expression, we’ve made it; we can then recursively apply this operation on the rest of the list. Strangely enough, it’s possible.

class DLCons[+T](override val value: T, p: => DLList[T], n: => DLList[T]) extends DLList[T] {
  // ... other methods

  override def updatePrev[S >: T](newPrev: => DLList[S]) = {
    lazy val result: DLCons[S] = new DLCons(value, newPrev, n.updatePrev(result))
    result
  }
  
}

Look at updatePrev: we’re creating a new node, whose next reference immediately points to a recursive call; the recursive call is on the current next node, which will update its own previous reference to the result we’re still in the process of defining! This forward reference is only possible in the presence of lazy values and the by-name arguments.