1 // Copyright 2010 Bill Burdick. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
10 import "container/vector"
12 type Element
interface{}
13 type SeqChan
chan Element
14 type Sequence
func()SeqChan
16 func IsSeq(s
interface{}) bool {
17 _
, test
:= s
.(Sequence
)
21 // f must behave properly when the channel is closed, so that IsEmpty and First work properly
22 func Seq(f
func(c SeqChan
)) Sequence
{
23 return func() SeqChan
{
33 func From(el
... interface{}) Sequence
{
34 return Seq(func(c SeqChan
) {Output(c
, el
...)})
37 func Output(c SeqChan
, el
... interface{}) {
38 for _
, v
:= range el
{
43 func (s Sequence
) First() Element
{
49 func (s Sequence
) Rest() Sequence
{
57 func (s Sequence
) AddFirst(els
... interface{}) Sequence
{
58 return Seq(func(c SeqChan
){
66 func (s Sequence
) AddLast(els
... interface{}) Sequence
{
67 return Seq(func(c SeqChan
){
75 func (s Sequence
) IsEmpty() bool {
79 if !result
{defer close(c
)}
83 func (s Sequence
) Append(s2 Sequence
) Sequence
{
84 return Seq(func(c SeqChan
){
90 func (s Sequence
) Len() int {
100 func (s Sequence
) Output(c
chan Element
) {
101 for el
:= range s() {
106 func Upto(limit
int) Sequence
{
107 return Seq(func(c SeqChan
) {
108 for i
:= 0; i
< limit
; i
++ {
114 func (s Sequence
) Filter(filter
func(e Element
)bool) Sequence
{
115 return Seq(func(c SeqChan
){
116 for el
:= range s() {
124 func (s Sequence
) Do(f
func(el Element
)) {
130 func (s Sequence
) Map(f
func(i Element
)Element
) Sequence
{
131 return Seq(func(c SeqChan
) {
138 func (s Sequence
) FlatMap(f
func(i Element
) Sequence
) Sequence
{
139 return Seq(func(c SeqChan
) {
141 for sub
:= range f(v
)() {
148 func (s Sequence
) Fold(init Element
, f
func(acc
, el Element
)Element
) Element
{
149 for el
:= range s() {
155 //maybe convert this to use an accumulator instead of append?
156 func (s Sequence
) Combinations(number
int) Sequence
{
157 if number
== 0 || s
.IsEmpty() {return From(From())}
158 return s
.Rest().Combinations(number
- 1).Map(func(el Element
)Element
{
159 return el
.(Sequence
).AddFirst(s
.First())
160 }).Append(s
.Rest().Combinations(number
))
163 //returns the product of the Sequences contained in sequences
164 func (sequences Sequence
) Product() Sequence
{
165 return sequences
.Fold(From(From()), func(acc
, el Element
)Element
{
166 return el
.(Sequence
).peelOnto(acc
.(Sequence
))
170 func (s Sequence
) peelOnto(seq Sequence
) Sequence
{
171 return seq
.FlatMap(func(old Element
)Sequence
{
172 return s
.Map(func(i Element
) Element
{
173 return old
.(Sequence
).Append(From(i
))
178 func (s Sequence
) Reify() Sequence
{
179 vec
:= vector
.Vector(make([]interface{}, 0, 128))
181 sv
, is
:= v
.(Sequence
)
188 return From([]interface{}(vec
)...)
191 func (s Sequence
) ToVector() Vector
{
192 vec
:= vector
.Vector(make([]interface{}, 0, 128))
194 sv
, is
:= v
.(Sequence
)
196 vec
.Push(sv
.ToVector())
204 func (s Sequence
) Prettyln(names
map[Element
]string, writer
... io
.Writer
) {
205 if len(writer
) == 0 {
206 writer
= []io
.Writer
{os
.Stdout
}
208 s
.Pretty(names
, writer
...)
209 fmt
.Fprintln(writer
[0])
211 func (s Sequence
) Pretty(names
map[Element
]string, writer
... io
.Writer
) {
212 if len(writer
) == 0 {
213 writer
= []io
.Writer
{os
.Stdout
}
215 s
.prettyLevel(0, names
, writer
[0])
218 //This is pretty ugly :)
219 func (s Sequence
) prettyLevel(level
int, names
map[Element
]string, w io
.Writer
) {
220 name
, hasName
:= names
[s
]
225 fmt
.Fprintf(w
, "%*s%s", level
, "", "[")
231 _
,innerSeq
= v
.(Sequence
)
234 if !named
&& innerSeq
{
237 } else if !named
&& innerSeq
{
243 v
.(Sequence
).prettyLevel(level
+ 4, names
, w
)
245 fmt
.Fprintf(w
, "%v", v
)
250 fmt
.Fprintf(w
, "\n%*s", level
, "")