blob: 1fc7dc6f20c6b464083cbf73ec087d85b6b223ce [file] [log] [blame]
package ps
type List interface {
// IsNil returns true if the list is empty
IsNil() bool
// Cons returns a new list with val added onto the head
Cons(val Any) List
// Head returns the first element in the list or panics if the list is empty
Head() Any
// Tail returns the tail of this list or panics if the list is empty
Tail() List
// Size returns the list's length
Size() int
// ForEach executes a callback for each value in the list
ForEach(f func(Any))
// Reverse returns a list with elements in opposite order as this list
Reverse() List
}
// 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
}
func (self *list) IsNil() bool {
return self == nilList;
}
func (self *list) Size() int {
return self.depth
}
func (tail *list) Cons(val Any) List {
var xs list
xs.depth = tail.depth + 1
xs.value = val
xs.tail = tail
return &xs
}
func (self *list) Head() Any {
if self.IsNil() {
panic("Called Head() on an empty list")
}
return self.value
}
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
}