package main

import "fmt"

type TransformerFunction func(int) int

func NewCompositeTransformer(f, g TransformerFunction) TransformerFunction {
	return func(x int) int {
		return f(g(x))
	}
}

func Compose(f, g TransformerFunction, fs ...TransformerFunction) TransformerFunction {
	composite := NewCompositeTransformer(f, g)

	for _, f := range fs {
		composite = NewCompositeTransformer(composite, f)
	}

	return composite
}

func double(x int) int {
	return 2 * x
}

func inc(x int) int {
	return x + 1
}

func square(x int) int {
	return x * x
}

func main() {
	doubleThenIncThenSquare := Compose(square, inc, double)
	fmt.Println(doubleThenIncThenSquare(4))
}