A companion object is an object with the same name as a data type. It groups convenient functions for creating or working with that type and can access its private and protected members. section 3.2 section 3.6
The arrangement separates values from operations. A functional list can expose constructors such as Nil and Cons while List supplies construction and processing functions such as apply, sum, and product. section 3.2 section 3.1
Use a companion object to:
- Construct values conveniently with a variadic apply method, enabling syntax such as List(1, 2, 3). section 3.1
- Place operations over the type beside its definition, such as recursive sum and product functions for List. section 3.2
- Reach private and protected members of the type with the matching name. section 3.2
A list companion object
enum List[+A]: case Nil case Cons(head: A, tail: List[A]) object List: def apply[A](as: A*): List[A] = if as.isEmpty then Nil else Cons(as.head, apply(as.tail*)) The matching name lets callers write List(1, 2, 3) instead of assembling Cons and Nil manually. The same object can also hold functions such as sum and product. section 3.1 section 3.2
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*))
Inspect the complete singly linked list definition and its companion apply method. section 3.1

