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 {
83 func (s Sequence
) Append(s2 Sequence
) Sequence
{
84 return Seq(func(c SeqChan
){
90 func (s Sequence
) Len() int {
101 func (s Sequence
) Output(c
chan Element
) {
102 for el
:= range s() {
107 func Upto(limit
int) Sequence
{
108 return Seq(func(c SeqChan
) {
109 for i
:= 0; i
< limit
; i
++ {
115 func (s Sequence
) Filter(filter
func(e Element
)bool) Sequence
{
116 return Seq(func(c SeqChan
){
117 for el
:= range s() {
125 func (s Sequence
) Do(f
func(el Element
)) {
131 func (s Sequence
) Map(f
func(i Element
)Element
) Sequence
{
132 return Seq(func(c SeqChan
) {
139 func (s Sequence
) FlatMap(f
func(i Element
) Sequence
) Sequence
{
140 return Seq(func(c SeqChan
) {
142 for sub
:= range f(v
)() {
149 func (s Sequence
) Fold(init Element
, f
func(acc
, el Element
)Element
) Element
{
150 for el
:= range s() {
156 //maybe convert this to use an accumulator instead of append?
157 func (s Sequence
) Combinations(number
int) Sequence
{
158 if number
== 0 || s
.IsEmpty() {return From(From())}
159 return s
.Rest().Combinations(number
- 1).Map(func(el Element
)Element
{
160 return el
.(Sequence
).AddFirst(s
.First())
161 }).Append(s
.Rest().Combinations(number
))
164 //returns the product of the Sequences contained in sequences
165 func (sequences Sequence
) Product() Sequence
{
166 return sequences
.Fold(From(From()), func(acc
, el Element
)Element
{
167 return el
.(Sequence
).peelOnto(acc
.(Sequence
))
171 func (s Sequence
) peelOnto(seq Sequence
) Sequence
{
172 return seq
.FlatMap(func(old Element
)Sequence
{
173 return s
.Map(func(i Element
) Element
{
174 return old
.(Sequence
).Append(From(i
))
179 func (s Sequence
) Reify() Sequence
{
180 vec
:= vector
.Vector(make([]interface{}, 0, 128))
182 sv
, is
:= v
.(Sequence
)
189 return From([]interface{}(vec
)...)
192 func (s Sequence
) ToVector() Vector
{
193 vec
:= vector
.Vector(make([]interface{}, 0, 128))
195 sv
, is
:= v
.(Sequence
)
197 vec
.Push(sv
.ToVector())
205 func (s Sequence
) Prettyln(names
map[Element
]string, writer
... io
.Writer
) {
206 if len(writer
) == 0 {
207 writer
= []io
.Writer
{os
.Stdout
}
209 s
.Pretty(names
, writer
...)
210 fmt
.Fprintln(writer
[0])
212 func (s Sequence
) Pretty(names
map[Element
]string, writer
... io
.Writer
) {
213 if len(writer
) == 0 {
214 writer
= []io
.Writer
{os
.Stdout
}
216 s
.prettyLevel(0, names
, writer
[0])
219 //This is pretty ugly :)
220 func (s Sequence
) prettyLevel(level
int, names
map[Element
]string, w io
.Writer
) {
221 name
, hasName
:= names
[s
]
226 fmt
.Fprintf(w
, "%*s%s", level
, "", "[")
232 _
,innerSeq
= v
.(Sequence
)
235 if !named
&& innerSeq
{
238 } else if !named
&& innerSeq
{
244 v
.(Sequence
).prettyLevel(level
+ 4, names
, w
)
246 fmt
.Fprintf(w
, "%v", v
)
251 fmt
.Fprintf(w
, "\n%*s", level
, "")