39. package main
import "fmt"
func main() {
var c chan int
c = make(chan int)
limit := 16
go func() {
for i := limit; i > 0; i-- {
produces:
fmt.Print(<-c)
0110011101011010
}
}()
for i := limit; i > 0; i-- {
select {
case c <- 0:
case c <- 1:
}
}
}
40. func main() {
var c chan int
c = make(chan int, 16)
go func() {
for i := 16; i > 0; i-- {
fmt.Print(<-c)
}
}() produces:
go func() { 0110011101011010
select {
case c <- 0:
case c <- 1:
}
}()
for {}
}
41. package generalise
type SignalSource func(status chan bool)
func Wait(s SignalSource) {
done := make(chan bool)
defer close(done)
go s(done)
<-done
}
func WaitAll(count int, s SignalSource) {
done := make(chan bool)
defer close(done)
go s(done)
for i := 0; i < count; i++ {
<- done
}
}
42. type Iteration func(k, x interface{}) bool
func (i Iteration) apply(k, v interface{}, c chan bool) {
go func() {
c <-i(k, v)
}()
}
func (f Iteration) Each(c interface{}) {
switch c := ValueOf(c); c.Kind() {
case Slice: WaitAll(c.Len(), SignalSource(func(done chan bool) {
for i := 0; i < c.Len(); i++ {
f.apply(i, c.Elem(i).Interface(), done) }}))
case Map: WaitAll(c.Len(), SignalSource(func(done chan bool) {
for _, k := range c.Keys() {
f.apply(k, c.Elem(k).Interface(), done) }}))
}
}
43. type Results chan interface{}
type Combination func(x, y interface{}) interface{}
func (f Combination) Reduce(c, s interface{}) (r Results) {
r = make(Results)
go func() {
Iteration(func(k, x interface{}) (ok bool) {
s = f(s, x)
return true
}).Each(c)
r <- s
}()
return
}
44. type Transformation func(x interface{}) interface{}
func (t Transformation) Transform(x interface{}) Value {
return ValueOf(t(x))
}
func (t Transformation) Map(c interface{}) (r interface{}) {
r = Allocate(c)
if i := MapIterator(r); i != nil {
i.Each(c)
}
return
}
45. func MapIterator(c interface{}) (i Iteration) {
switch n := ValueOf(c); n.Kind() {
case Slice: i = Iteration(func(k, x interface{}) bool {
n.Elem(k.(int)).SetValue(t.GetValue(x))
return true
})
case Map: i = Iteration(func(k, x interface{}) bool {
n.SetMapIndex(ValueOf(k), t.GetValue(x))
return true
})
}
return
}
46. func main() {
s := []int{0, 1, 2, 3, 4, 5}
d := Transformation(func(x interface{}) interface{} {
return x.(int) * 2 }
).Map(s)
sum := Combination(func(x, y interface{}) interface{} {
return x.(int) + y.(int)
})
fmt.Printf("s = %v, sum = %vn", s, (<- sum.Reduce(s, 0)).(int))
fmt.Printf("d = %v, sum = %vn", d, (<- sum.Reduce(d, 0)).(int))
}
produces:
s = [0 1 2 3 4 5], sum = 15
d = [0 2 4 6 8 10], sum = 30