From 953116eedf7f90cd9870f9a99d373e1f4811dd8d Mon Sep 17 00:00:00 2001 From: oybek Date: Thu, 7 Sep 2023 13:52:55 +0600 Subject: [PATCH] Add Compose --- func.go | 27 +++++++++++++++++++++++++++ func_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/func.go b/func.go index 5fa1cbc8..9e33156f 100644 --- a/func.go +++ b/func.go @@ -39,3 +39,30 @@ func Partial5[T1, T2, T3, T4, T5, T6, R any](f func(T1, T2, T3, T4, T5, T6) R, a return f(arg1, t2, t3, t4, t5, t6) } } + +// Compose returns new function that is the composition of 2 functions passed as arguments +func Compose[T1, T2, T3 any](f1 func(T1) T2, f2 func(T2) T3) func(T1) T3 { + return func(t1 T1) T3 { + return f2(f1(t1)) + } +} + +// Compose2 returns new function that is the composition of 2 functions passed as arguments +func Compose2[T1, T2, T3 any](f1 func(T1) T2, f2 func(T2) T3) func(T1) T3 { + return Compose(f1, f2) +} + +// Compose3 returns new function that is the composition of 3 functions passed as arguments +func Compose3[T1, T2, T3, T4 any](f1 func(T1) T2, f2 func(T2) T3, f3 func(T3) T4) func(T1) T4 { + return Compose(Compose(f1, f2), f3) +} + +// Compose4 returns new function that is the composition of 4 functions passed as arguments +func Compose4[T1, T2, T3, T4, T5 any](f1 func(T1) T2, f2 func(T2) T3, f3 func(T3) T4, f4 func(T4) T5) func(T1) T5 { + return Compose(Compose(Compose(f1, f2), f3), f4) +} + +// Compose5 returns new function that is the composition of 5 functions passed as arguments +func Compose5[T1, T2, T3, T4, T5, T6 any](f1 func(T1) T2, f2 func(T2) T3, f3 func(T3) T4, f4 func(T4) T5, f5 func(T5) T6) func(T1) T6 { + return Compose(Compose(Compose(Compose(f1, f2), f3), f4), f5) +} diff --git a/func_test.go b/func_test.go index 284d24a4..7a7a6d20 100644 --- a/func_test.go +++ b/func_test.go @@ -78,3 +78,52 @@ func TestPartial5(t *testing.T) { is.Equal("26", f(10, 9, -3, 0, 5)) is.Equal("21", f(-5, 8, 7, -1, 7)) } + +func TestCompose(t *testing.T) { + t.Parallel() + is := assert.New(t) + + filterEven := func(ns []int) []int { + return Filter(ns, func(x int, i int) bool { return x%2 == 0 }) + } + sum := func(ns []int) int { + return ReduceRight(ns, func(sum int, x int, i int) int { return sum + x }, 0) + } + result := Compose(filterEven, sum)([]int{1, 2, 3, 4, 5}) + is.Equal("6", strconv.Itoa(result)) +} + +func TestCompose2(t *testing.T) { + t.Parallel() + is := assert.New(t) + + filterEven := func(ns []int) []int { + return Filter(ns, func(x int, i int) bool { return x%2 == 0 }) + } + sum := func(ns []int) int { + return ReduceRight(ns, func(sum int, x int, i int) int { return sum + x }, 0) + } + result := Compose2(filterEven, sum)([]int{1, 2, 3, 4, 5}) + is.Equal("6", strconv.Itoa(result)) +} + +func TestCompose3(t *testing.T) { + t.Parallel() + is := assert.New(t) + + filterEven := func(ns []int) []int { + return Filter(ns, func(x int, i int) bool { return x%2 == 0 }) + } + mulEachBy10 := func(ns []int) []int { + return Map(ns, func(x int, i int) int { return x * 10 }) + } + sum := func(ns []int) int { + return ReduceRight(ns, func(sum int, x int, i int) int { return sum + x }, 0) + } + result := Compose3( + filterEven, + mulEachBy10, + sum, + )([]int{1, 2, 3, 4, 5}) + is.Equal("60", strconv.Itoa(result)) +}