mal-go/list/list.go
ajet 4e1cbce3a7
Some checks failed
Go / test (push) Failing after 28s
start the tower of abstractions
2025-11-04 12:25:23 -10:00

129 lines
1.8 KiB
Go

package list
import (
"fmt"
"strings"
)
type IList interface {
Conj(data any) IList
First() any
Rest() IList
String() string
}
type EmptyList struct{}
type List struct {
Value any
next IList
}
func New() IList {
return new(EmptyList)
}
func single(val any) *List {
this := new(List)
this.Value = val
this.next = nil
return this
}
func (this *List) Conj(val any) IList {
if this == nil {
return single(val)
}
new_head := single(val)
new_head.next = this
return new_head
}
func (this *EmptyList) Conj(val any) IList {
return Conj(nil, val)
}
func Conj(this IList, val any) IList {
var l IList
if this == nil {
l = single(val)
} else {
l = this
}
return l.Conj(val)
}
func Rest(this IList) IList {
if this == nil {
return nil
}
return this.Rest()
}
func (this *List) Rest() IList {
if this == nil {
return nil
}
return this.next
}
func (this *EmptyList) Rest() IList {
return nil
}
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 IList) 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
var e IList
for e = this; e != nil; e = Rest(e) {
switch v := e.(type) {
case *List:
sb.WriteString(fmt.Sprint(v.Value))
sb.WriteRune(' ')
case *EmptyList:
break
}
}
return sb.String()[:sb.Len()-1] + ")"
}
func (this *List) String() string {
return String(this)
}
func (this *EmptyList) String() string {
return String(nil)
}