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 Element
) bool {
17 _
, test
:= s
.(Sequence
)
21 func Seq(f
func(c SeqChan
)) Sequence
{
22 return func() SeqChan
{
32 func From(el
... interface{}) Sequence
{
33 return Seq(func(c SeqChan
) {Output(c
, el
...)})
36 func Output(c SeqChan
, el
... interface{}) {
37 for _
, v
:= range el
{
42 func Bleed(c SeqChan
) {
48 func (s Sequence
) First() Element
{
54 func (s Sequence
) Rest() Sequence
{
62 func (s Sequence
) AddFirst(els
... interface{}) Sequence
{
63 return Seq(func(c SeqChan
){
71 func (s Sequence
) AddLast(els
... interface{}) Sequence
{
72 return Seq(func(c SeqChan
){
80 func (s Sequence
) IsEmpty() bool {
84 if !result
{defer Bleed(c
)}
88 func (s Sequence
) Append(s2 Sequence
) Sequence
{
89 return Seq(func(c SeqChan
){
95 func (s Sequence
) Len() int {
105 func (s Sequence
) Output(c
chan Element
) {
106 for el
:= range s() {
111 func Upto(limit
int) Sequence
{
112 return Seq(func(c SeqChan
) {
113 for i
:= 0; i
< limit
; i
++ {
119 func (s Sequence
) Filter(filter
func(e Element
)bool) Sequence
{
120 return Seq(func(c SeqChan
){
121 for el
:= range s() {
129 func (s Sequence
) Do(f
func(el Element
)) {
135 func (s Sequence
) Map(f
func(i Element
)Element
) Sequence
{
136 return Seq(func(c SeqChan
) {
143 func (s Sequence
) FlatMap(f
func(i Element
) Sequence
) Sequence
{
144 return Seq(func(c SeqChan
) {
146 for sub
:= range f(v
)() {
153 func (s Sequence
) Fold(init Element
, f
func(acc
, el Element
)Element
) Element
{
154 for el
:= range s() {
160 //maybe convert this to use an accumulator instead of append?
161 func (s Sequence
) Combinations(number
int) Sequence
{
162 if number
== 0 || s
.IsEmpty() {return From(From())}
163 return s
.Rest().Combinations(number
- 1).Map(func(el Element
)Element
{
164 return el
.(Sequence
).AddFirst(s
.First())
165 }).Append(s
.Rest().Combinations(number
))
168 func (sequences Sequence
) Product() Sequence
{
169 return sequences
.Fold(From(From()), func(acc
, el Element
)Element
{
170 return el
.(Sequence
).PeelOnto(acc
.(Sequence
))
174 func (s Sequence
) PeelOnto(result Sequence
) Sequence
{
175 return result
.FlatMap(func(old Element
)Sequence
{
176 return s
.Map(func(i Element
) Element
{
177 return old
.(Sequence
).Append(From(i
))
182 func (s Sequence
) Reify() Sequence
{
183 vec
:= vector
.Vector(make([]interface{}, 0, 128))
185 sv
, is
:= v
.(Sequence
)
192 return From([]interface{}(vec
)...)
195 func (s Sequence
) Prettyln(names
map[Element
]string, writer
... io
.Writer
) {
196 if len(writer
) == 0 {
197 writer
= []io
.Writer
{os
.Stdout
}
199 s
.Pretty(names
, writer
...)
200 fmt
.Fprintln(writer
[0])
202 func (s Sequence
) Pretty(names
map[Element
]string, writer
... io
.Writer
) {
203 if len(writer
) == 0 {
204 writer
= []io
.Writer
{os
.Stdout
}
206 s
.prettyLevel(0, names
, writer
[0])
209 //This is pretty ugly :)
210 func (s Sequence
) prettyLevel(level
int, names
map[Element
]string, w io
.Writer
) {
211 name
, hasName
:= names
[s
]
216 fmt
.Fprintf(w
, "%*s%s", level
, "", "[")
222 _
,innerSeq
= v
.(Sequence
)
225 if !named
&& innerSeq
{
228 } else if !named
&& innerSeq
{
234 v
.(Sequence
).prettyLevel(level
+ 4, names
, w
)
236 fmt
.Fprintf(w
, "%v", v
)
241 fmt
.Fprintf(w
, "\n%*s", level
, "")