liveBook · Manning

Pure functional data structure

As explained in Functional Programming in Scala, Second Edition

A purely functional data structure is an immutable data structure whose operations produce new values without mutating existing ones.

A pure functional data structure is immutable and operated on only through pure functions. Operations return new values without changing existing data, so earlier references remain valid. section 3.1 section 3.6

A singly linked list makes the design concrete: Nil represents an empty list, while Cons stores a head and a tail. Pattern matching exposes these constructors for recursive processing. section 3.1 section 3.6

Sharing an immutable list

Given xs, prepending 1 returns Cons(1, xs) without copying xs. Removing the first element returns xs itself. These operations preserve the original list through persistence, also called structural sharing. Prepending and taking the tail can therefore avoid copying, while replacing a tail near the end may require copying preceding Cons objects. section 3.3 section 3.3.1

Typical operations illustrate the trade-offs of immutable structure:

  • Implement tail to return every element after the first, handling Nil explicitly. section 3.3
  • Implement setHead by constructing a list with a replacement first element. section 3.3
  • Implement init to return all but the last element and examine why it cannot run in constant time. section 3.3.1
Listing 3.1 Singly linked lists
package fpinscala.datastructures
 
enum List[+A]:                            #1
  case Nil                                #2
  case Cons(head: A, tail: List[A])       #3
 
object List:                              #4
  def apply[A](as: A*): List[A] =         #5
    if as.isEmpty then Nil
    else Cons(as.head, apply(as.tail*))

The list definition shows the two constructors and the companion-object apply function used to build lists recursively. section 3.1

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines immutable lists, sharing, persistence, and operation costs, but defers broader efficient functional data-structure designs.
Examples
Uses Scala singly linked lists with Nil and Cons, including tail, setHead, init, append, map, filter, and flatMap.
What you can do after
Build immutable lists and pure recursive operations while reasoning about sharing, persistence, and copying costs.
How it connects
Connects pure functions with algebraic data types, pattern matching, recursion, persistence, and higher-order functions.

Also explained in

Compare how 2 books explain pure functional data structure →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Programming in Scala, Second Edition. The section links point to the parts of the book it draws on.