blob: d285d27a95a7c142f60b7de3b46737052220226f [file] [log] [blame]
package ps
// Immutable (i.e. persistent) list
type List struct {
depth int // the number of nodes after, and including, this one
value Any
tail *List
}
// An empty list shared by all lists
var nilList = &List{}
// NewList returns a new, empty list
func NewList() *List {
return nilList
}
// IsNil returns true if the list is empty
func (self *List) IsNil() bool {
return self == nilList;
}
// Size returns the list's length
func (self *List) Size() int {
return self.depth
}
// Cons returns a new list with val added onto the head
func (tail *List) Cons(val Any) *List {
var list List
list.depth = tail.depth + 1
list.value = val
list.tail = tail
return &list
}
// Head returns the first element in the list or panics if the list is empty
func (self *List) Head() Any {
if self.IsNil() {
panic("Called Head() on an empty list")
}
return self.value
}
// Tail returns the tail of this list or panics if the list is empty
func (self *List) Tail() *List {
if self.IsNil() {
panic("Called Tail() on an empty list")
}
return self.tail
}
// ForEach executes a callback for each value in the list
func (self *List) ForEach(f func(Any)) {
if self.IsNil() {
return
}
f(self.Head())
self.Tail().ForEach(f)
}
// Reverse returns a list with elements in opposite order as this list
func (self *List) Reverse() *List {
reversed := NewList()
self.ForEach( func (v Any) { reversed = reversed.Cons(v) })
return reversed
}