list.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package ps
  2. // List is a persistent list of possibly heterogenous values.
  3. type List interface {
  4. // IsNil returns true if the list is empty
  5. IsNil() bool
  6. // Cons returns a new list with val as the head
  7. Cons(val interface{}) List
  8. // Head returns the first element of the list;
  9. // panics if the list is empty
  10. Head() interface{}
  11. // Tail returns a list with all elements except the head;
  12. // panics if the list is empty
  13. Tail() List
  14. // Size returns the list's length. This takes O(1) time.
  15. Size() int
  16. // ForEach executes a callback for each value in the list.
  17. ForEach(f func(interface{}))
  18. // Reverse returns a list whose elements are in the opposite order as
  19. // the original list.
  20. Reverse() List
  21. }
  22. // Immutable (i.e. persistent) list
  23. type list struct {
  24. depth int // the number of nodes after, and including, this one
  25. value interface{}
  26. tail *list
  27. }
  28. // An empty list shared by all lists
  29. var nilList = &list{}
  30. // NewList returns a new, empty list. The result is a singly linked
  31. // list implementation. All lists share an empty tail, so allocating
  32. // empty lists is efficient in time and memory.
  33. func NewList() List {
  34. return nilList
  35. }
  36. func (self *list) IsNil() bool {
  37. return self == nilList
  38. }
  39. func (self *list) Size() int {
  40. return self.depth
  41. }
  42. func (tail *list) Cons(val interface{}) List {
  43. var xs list
  44. xs.depth = tail.depth + 1
  45. xs.value = val
  46. xs.tail = tail
  47. return &xs
  48. }
  49. func (self *list) Head() interface{} {
  50. if self.IsNil() {
  51. panic("Called Head() on an empty list")
  52. }
  53. return self.value
  54. }
  55. func (self *list) Tail() List {
  56. if self.IsNil() {
  57. panic("Called Tail() on an empty list")
  58. }
  59. return self.tail
  60. }
  61. // ForEach executes a callback for each value in the list
  62. func (self *list) ForEach(f func(interface{})) {
  63. if self.IsNil() {
  64. return
  65. }
  66. f(self.Head())
  67. self.Tail().ForEach(f)
  68. }
  69. // Reverse returns a list with elements in opposite order as this list
  70. func (self *list) Reverse() List {
  71. reversed := NewList()
  72. self.ForEach(func(v interface{}) { reversed = reversed.Cons(v) })
  73. return reversed
  74. }