diff --git a/list/list.go b/list/list.go index 9fc582d..a7956b7 100644 --- a/list/list.go +++ b/list/list.go @@ -5,11 +5,17 @@ import ( "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) } @@ -28,6 +34,10 @@ 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) @@ -59,13 +69,25 @@ 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 "{}" + return "()" } var sb strings.Builder sb.WriteRune('(') diff --git a/list/list_test.go b/list/list_test.go new file mode 100644 index 0000000..e05765f --- /dev/null +++ b/list/list_test.go @@ -0,0 +1,25 @@ +package list + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestReadConj(t *testing.T) { + l := Empty().Conj(5).Conj(6).Conj(7) + assert.Equal(t, "(7 6 5)", l.String(), "should insert at head") +} + +func TestReadFirst(t *testing.T) { + l := Empty().Conj(5).Conj(6).Conj(7) + assert.Equal(t, 7, l.First(), "should return first element") + assert.Equal(t, nil, Empty().First(), "should return nil") + assert.Equal(t, 5, New(5).First(), "should get first from New") +} + +func TestReadRest(t *testing.T) { + l := Empty().Conj(5).Conj(6).Conj(7) + assert.Equal(t, "(6 5)", l.Rest().String(), "should return rest sublist") + assert.Equal(t, "(5)", l.Rest().Rest().String(), "should return rest sublist") + assert.Equal(t, "()", l.Rest().Rest().Rest().String(), "should return rest sublist") +}