We need to have a way to append items to LinkedList; we name it cons.
cons refers to a fundamental function in most dialects of the Lisp programming language that constructs memory objects that hold two values or pointers to values.
It is loosely related to the object-oriented notion of a constructor/initializer, and more closely related to the constructor function of an algebraic data type system.
In FP jargon, operators that have a similar purpose, especially in the context of list or collection processing, are pronounced cons.
We implement cons as follows:
func cons(_ element: Element) -> LinkedList {
return .node(data: element, next: self)
}
This simple method appends the data to the front of LinkedList; in other words, it is like a push operation to a stack.
We can test it as follows:
let functionalLinkedList = LinkedList<Int>.end.cons(1).cons(2).cons(3)
The result of this operation should be the following:
node(3, LinkedList<Swift.Int>.node(2, LinkedList<Swift.Int>.node(1, LinkedList<Swift.Int>.end)))
FP languages such as Haskell and Scala have operators for cons. It is : in Haskell and :: in Scala. As we cannot use : in Swift to define an infix operator, we are going to use <| instead:
precedencegroup AssociativityRight {
associativity: right
}
infix operator <| : AssociativityRight
func <| <T>(lhs: T, rhs: LinkedList<T>) -> LinkedList<T> {
return .node(data: lhs, next: rhs)
}
We will be able to test it as follows:
let functionalLLWithCons = 3 <| 2 <| 1 <| .end
This statement produces the exact same result.
Again, this LinkedList is far from complete but we already achieved great reusability as it is functional. We can use/share our functionalLinkedList with other linked lists without worrying about changes and inconsistencies. Let's examine the following:
let secondLL = functionalLinkedList.cons(4)
let thirdLL = functionalLinkedList.cons(5)
let fourthLL = LinkedList<Int>.node(data: 1, next: secondLL)
In the preceding examples, we use functionalLinkedList and add a new item 4 to it to obtain secondLL and 5 to obtain thirdLL. Also, we use secondLL to create fourthLL.