Summary

Concept of linked lists, data & ptr to next node

js
const x = pair(1, pair(null, pair(2, null)));
// or
const x = list(1, null, 2);

// Box notation: [1, [2, [3, null]]]
x12

Shortcuts

js
map(f, null) => null
map(f, list(null)) => list(f(null))

append(null, null) => null
append(list(a), null) => list(a)

enum_list(0, n-1) => list(0,...,n-1) : length = n
enum_list(1, n) => list(1,...,n) : length = n
build_list(f, n) => list(f(0),...f(n-1)) : length = n

for_each(f, xs) // like map but doesn't return a list
filer(pred, xs) // preserves true only
accumulate(f, initial, null) => initial
accumulate(f, initial, list(a)) => f(a, initial)

Concept

A list is either:

  • null
  • or a pair, whose tail is a list(ie. tail can be null also)

Think of it as a linked list, where each “node” contains the value(any type) of at the current index, and the pointer to the next node

Exampleis_list
nulltrue
pair(1, null)true
pair(1, pair(2, null))true
pair(1, pair(2, 3))false
pair(pair(1, 2), pair(3, null))true
pair(null, pair(null, null))true
Can be created using the list function
list(1, 2, 3) is the same as

Application

List Processing Summary Functions

FunctionActionVisualiseExamples
pair(x, y)Makes a pair from x and y.
head(p)Returns the head (first component) of the pair p.head(pair(a,b)) -> a
tail(p)Returns the tail (second component) of the pair p.head(pair(a,b)) -> b
is_null(xs)Returns true if xs is the empty list null, and false otherwise.is_null(null) -> true, is_null(pair(1, null)) -> false
list(x1, x2,…, xn)Returns a list with n elements. The first element is x1, the second x2, etc.
length(xs)Returns the length of the list xs.length(list(1, 2)) -> 2
list_ref(xs, n)Returns the element of list xs at position n. (List indexing)list_ref(list(1, 2), 0) -> 1
append(xs, ys)Returns a list that results from appending the list ys to the list xs.append(list(1, 2), list(3, 4)) -> list(1, 2, 3, 4)
reverse(xs)Returns new list containing the elements of xs in reverse order.reverse(list(1, 2, 3)) -> list(3, 2, 1)
map(f, xs)Returns a list where unary function f is applied to each element in the list xs.list(f(x1), f(x2), … f(xn))map(x => x * x, list(1, 2, 3)) -> lisr(1, 4, 9)
(Square each Element)
filter(pred, xs)Returns a list of the elements from xs that the unary function pred returns true from.filter(x => x % 2 === 0, list(1, 2, 3, 4)) -> list(2, 4)
(Even Only)
accumulate(f, initial, xs)Applies the binary function f to the nth element and initial, then to the (n-1)th
element and the previous result, etc, up until the 1st element of xs.
f(x1, f(x2, … f(xn, initial) … )accumulate((h, t) => h + t, 0, list(1, 2, 3)) -> 6
(Sum)
List processing functions
js
function length(xs) { 
	return is_null(xs)            
		   ? 0             
		   : 1 + length(tail(xs));
}

function append(xs, ys) {     
	return is_null(xs)            
		   ? ys            
		   : pair(head(xs), append2(tail(xs), ys));
}

function reverse(xs) {
	function rev(xs, reversed) {
		return is_null(xs)
			   ? null
			   : rev(tail(xs),
				     pair(head(xs), reversed)));
	}
	return rev(xs, null);
}

Higher order list processing functions

js
function map(f, xs) {
	return is_null(xs)            
		   ? null            
		   : pair(f(head(xs)), map(f, tail(xs)));
}

function filter(pred, xs) {
	return is_null(xs)
		   ? null            
		   : pred(head(xs))            
		   ? pair(head(xs), filter(pred, tail(xs)))            
		   : filter(pred, tail(xs));
} 

function accumulate(op, initial, xs) {     
	return is_null(xs)            
		   ? initial            
		   : op(head(xs),                  
				accumulate(op, initial, tail(xs)));
} 

Bonus

js
function zip(xs, ys) {
	return is_null(xs) || is_null(ys)
		   ? null
		   : pair(pair(head(xs), head(ys)),
				  zip(tail(xs), tail(ys)));
}