Loading functional/functional.go 0 → 100644 +79 −0 Original line number Diff line number Diff line package functional // IsEven ... func IsEven(n int) bool { return (n % 2) == 0 } // IsOdd ... func IsOdd(n int) bool { return !IsEven(n) } // AddN ... func AddN(n int) func(v int) int { return func(v int) int { return v + n } } // Add ... func Add(a, b int) int { return a + b } // Mul ... func Mul(a, b int) int { return a * b } // Map ... func Map(vi []int, t func(v int) int) []int { vo := make([]int, len(vi)) for i := range vi { vo[i] = t(vi[i]) } return vo } // IntSlice ... type IntSlice []int // Map ... func (vi IntSlice) Map(t func(v int) int) IntSlice { return Map(vi, t) } // Reduce ... func Reduce(vi IntSlice, b int, t func(a, b int) int) int { r := b for i := range vi { r = t(r, vi[i]) } return r } // Reduce ... func (vi IntSlice) Reduce(b int, t func(a, b int) int) int { return Reduce(vi, b, t) } // Filter ... func Filter(vi []int, t func(v int) bool) IntSlice { vo := []int{} for _, v := range vi { if t(v) { vo = append(vo, v) } } return vo } // Filter ... func (vi IntSlice) Filter(t func(v int) bool) IntSlice { return Filter(vi, t) } functional/functional_test.go 0 → 100644 +67 −0 Original line number Diff line number Diff line package functional import ( "testing" ) func TestIsX(t *testing.T) { for _, tv := range []struct { n int b bool }{ {n: 0, b: true}, {n: 1, b: false}, {n: 2, b: true}, {n: 13, b: false}, {n: 100, b: true}, } { if b := IsEven(tv.n); b != tv.b { t.Errorf("isEven(%d) is %t, expected %t", tv.n, b, tv.b) } if b := IsOdd(tv.n); b == tv.b { t.Errorf("isOdd(%d) is %t, expected %t", tv.n, b, !tv.b) } } } func TestConcurrency1(t *testing.T) { vi := IntSlice{0, 1, 2, 3, 4} vr := []int{5, 6, 7, 8, 9} vx := []int{5, 7, 9} add5 := AddN(5) vo := Map(vi, add5) for i := range vi { if vr[i] != vo[i] { t.Errorf("vo[%d] is %d, expected %d", i, vo[i], vr[i]) } } s := Reduce(vo, 0, Add) if s != 35 { t.Errorf("Reduce(%v, 0, Add) is %d, expected 35", vo, s) } vf := Filter(vo, IsOdd) for i := range vf { if vx[i] != vf[i] { t.Errorf("vf[%d] is %d, expected %d", i, vf[i], vx[i]) } } y := Reduce(vf, 1, Mul) if y != 315 { t.Errorf("Reduce(%v, 0, Add) is %d, expected 315", vf, y) } z := vi.Map(add5).Filter(IsOdd).Reduce(1, Mul) if z != 315 { t.Errorf("%v... is %d, expected 315", vi, z) } } Loading
functional/functional.go 0 → 100644 +79 −0 Original line number Diff line number Diff line package functional // IsEven ... func IsEven(n int) bool { return (n % 2) == 0 } // IsOdd ... func IsOdd(n int) bool { return !IsEven(n) } // AddN ... func AddN(n int) func(v int) int { return func(v int) int { return v + n } } // Add ... func Add(a, b int) int { return a + b } // Mul ... func Mul(a, b int) int { return a * b } // Map ... func Map(vi []int, t func(v int) int) []int { vo := make([]int, len(vi)) for i := range vi { vo[i] = t(vi[i]) } return vo } // IntSlice ... type IntSlice []int // Map ... func (vi IntSlice) Map(t func(v int) int) IntSlice { return Map(vi, t) } // Reduce ... func Reduce(vi IntSlice, b int, t func(a, b int) int) int { r := b for i := range vi { r = t(r, vi[i]) } return r } // Reduce ... func (vi IntSlice) Reduce(b int, t func(a, b int) int) int { return Reduce(vi, b, t) } // Filter ... func Filter(vi []int, t func(v int) bool) IntSlice { vo := []int{} for _, v := range vi { if t(v) { vo = append(vo, v) } } return vo } // Filter ... func (vi IntSlice) Filter(t func(v int) bool) IntSlice { return Filter(vi, t) }
functional/functional_test.go 0 → 100644 +67 −0 Original line number Diff line number Diff line package functional import ( "testing" ) func TestIsX(t *testing.T) { for _, tv := range []struct { n int b bool }{ {n: 0, b: true}, {n: 1, b: false}, {n: 2, b: true}, {n: 13, b: false}, {n: 100, b: true}, } { if b := IsEven(tv.n); b != tv.b { t.Errorf("isEven(%d) is %t, expected %t", tv.n, b, tv.b) } if b := IsOdd(tv.n); b == tv.b { t.Errorf("isOdd(%d) is %t, expected %t", tv.n, b, !tv.b) } } } func TestConcurrency1(t *testing.T) { vi := IntSlice{0, 1, 2, 3, 4} vr := []int{5, 6, 7, 8, 9} vx := []int{5, 7, 9} add5 := AddN(5) vo := Map(vi, add5) for i := range vi { if vr[i] != vo[i] { t.Errorf("vo[%d] is %d, expected %d", i, vo[i], vr[i]) } } s := Reduce(vo, 0, Add) if s != 35 { t.Errorf("Reduce(%v, 0, Add) is %d, expected 35", vo, s) } vf := Filter(vo, IsOdd) for i := range vf { if vx[i] != vf[i] { t.Errorf("vf[%d] is %d, expected %d", i, vf[i], vx[i]) } } y := Reduce(vf, 1, Mul) if y != 315 { t.Errorf("Reduce(%v, 0, Add) is %d, expected 315", vf, y) } z := vi.Map(add5).Filter(IsOdd).Reduce(1, Mul) if z != 315 { t.Errorf("%v... is %d, expected 315", vi, z) } }