mal-go/list/list.go
ajet d3997bfb53
All checks were successful
Go / test (push) Successful in 2s
support non-nil empty list
2025-11-04 11:50:38 -10:00

105 lines
1.5 KiB
Go

package list
import (
"fmt"
"strings"
)
type EmptyList struct{}
type List struct {
Value any
next *List
}
func Empty() *EmptyList {
return new(EmptyList)
}
func New(val any) *List {
return new(List).Init(val)
}
func (this *List) Init(val any) *List {
return Init(this, val)
}
func Init(this *List, val any) *List {
this.Value = val
this.next = nil
return this
}
func (this *List) Conj(val any) *List {
return Conj(this, val)
}
func (this *EmptyList) Conj(val any) *List {
return Conj(nil, val)
}
func Conj(this *List, val any) *List {
if this == nil {
return New(val)
}
new_head := New(val)
new_head.next = this
return new_head
}
func Rest(this *List) *List {
if this == nil {
return nil
}
return this.next
}
func (this *List) Rest() *List {
return Rest(this)
}
func First(this *List) any {
if this == nil {
return nil
}
return this.Value
}
func (this *List) First() any {
return First(this)
}
func (this *EmptyList) First() any {
return First(nil)
}
func IsEmpty(this *List) bool {
return this == nil
}
func (this *List) IsEmpty() bool {
return this == nil
}
func (this *EmptyList) IsEmpty() bool {
return true
}
func String(this *List) string {
if this == nil {
return "()"
}
var sb strings.Builder
sb.WriteRune('(')
// Iterate and print elements
for e := this; e != nil; e = Rest(e) {
sb.WriteString(fmt.Sprint(e.Value))
sb.WriteRune(' ')
}
return sb.String()[:sb.Len()-1] + ")"
}
func (this *List) String() string {
return String(this)
}