mal-go/list/list.go
Adam Jeniski d573528f3b
All checks were successful
Go / test (push) Successful in 4s
update IColl asbstractions
2025-11-04 18:33:05 -10:00

103 lines
1.4 KiB
Go

package list
import (
"fmt"
"strings"
)
type ICollection interface {
Conj(data any) IList
IsEmpty() bool
String() string
Len() int
}
type ISeq interface {
First() any
Rest() IList
}
type IList interface {
ISeq
ICollection
}
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 (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; !e.IsEmpty(); 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()
}