Skip to content

Instantly share code, notes, and snippets.

@icholy
Last active February 20, 2017 01:44
Show Gist options
  • Select an option

  • Save icholy/5449954 to your computer and use it in GitHub Desktop.

Select an option

Save icholy/5449954 to your computer and use it in GitHub Desktop.
chaining channels in go
package main
import (
"unicode/utf8"
)
type Item string
type Stream chan Item
type Acc string
func NewWordStream(words []Item) Stream {
stream := make(Stream)
go func() {
for _, w := range words {
stream <- w
}
close(stream)
}()
return stream
}
func (in Stream) Map(fn func(Item) Item) Stream {
out := make(Stream)
go func() {
for x := range in {
out <- fn(x)
}
close(out)
}()
return out
}
func (in Stream) Filter(fn func(Item) bool) Stream {
out := make(Stream)
go func() {
for x := range in {
if fn(x) {
out <- x
}
}
close(out)
}()
return out
}
func (in Stream) Reduce(fn func(Acc, Item) (Acc, Acc)) chan Acc {
out := make(chan Acc)
go func() {
var val, acc Acc
for x := range in {
acc, val = fn(acc, x)
if val != "" {
out <- val
}
}
close(out)
}()
return out
}
func main() {
reverse := func(word Item) Item {
s := string(word)
o := make([]rune, utf8.RuneCountInString(s))
i := len(o)
for _, c := range s {
i--
o[i] = c
}
return Item(o)
}
longerThan := func(n int) func(Item) bool {
return func(w Item) bool {
return len(w) > n
}
}
not := func(s string) func(Item) bool {
return func(w Item) bool {
return s != string(w)
}
}
words := []Item{"this", "is", "pretty", "cool"}
stream :=NewWordStream(words).Map(reverse).Filter(longerThan(2)).Map(reverse).Filter(not("this"))
for w := range stream {
println(w)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment