107 lines
1.5 KiB
Go
107 lines
1.5 KiB
Go
package list
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type ICollection interface {
|
|
Conj(data any) IList
|
|
IsEmpty() bool
|
|
}
|
|
|
|
type ISeq interface {
|
|
First() any
|
|
Rest() IList
|
|
}
|
|
|
|
type IList interface {
|
|
ISeq
|
|
ICollection
|
|
String() string
|
|
Len() int
|
|
}
|
|
|
|
type EmptyList struct{}
|
|
|
|
type List struct {
|
|
Value any
|
|
next IList
|
|
}
|
|
|
|
func Empty() IList {
|
|
return new(EmptyList)
|
|
}
|
|
|
|
var emptyList = Empty()
|
|
|
|
func New(val any) *List {
|
|
this := new(List)
|
|
this.Value = val
|
|
this.next = emptyList
|
|
return this
|
|
}
|
|
|
|
func (this *List) Conj(val any) IList {
|
|
new_head := New(val)
|
|
new_head.next = this
|
|
return new_head
|
|
|
|
}
|
|
|
|
func (this *EmptyList) Conj(val any) IList {
|
|
return New(val)
|
|
}
|
|
|
|
func (this *List) Rest() IList {
|
|
return this.next
|
|
}
|
|
|
|
func (this *EmptyList) Rest() IList {
|
|
return emptyList
|
|
}
|
|
|
|
func (this *List) First() any {
|
|
return this.Value
|
|
}
|
|
|
|
func (this *EmptyList) First() any {
|
|
return nil
|
|
}
|
|
|
|
func IsEmpty(this IList) bool {
|
|
return this == nil || this.IsEmpty()
|
|
}
|
|
|
|
func (this *List) IsEmpty() bool {
|
|
return false
|
|
}
|
|
|
|
func (this *EmptyList) IsEmpty() bool {
|
|
return true
|
|
}
|
|
|
|
func (this *List) String() string {
|
|
var sb strings.Builder
|
|
sb.WriteRune('(')
|
|
// Iterate and print elements
|
|
var e IList
|
|
for e = this; !IsEmpty(e); e = e.Rest() {
|
|
sb.WriteString(fmt.Sprint(e.First()))
|
|
sb.WriteRune(' ')
|
|
}
|
|
return sb.String()[:sb.Len()-1] + ")"
|
|
}
|
|
|
|
func (this *EmptyList) String() string {
|
|
return "()"
|
|
}
|
|
|
|
func (this *EmptyList) Len() int {
|
|
return 0
|
|
}
|
|
|
|
func (this *List) Len() int {
|
|
return 1 + this.Rest().Len()
|
|
}
|