Output of the inner function becomes the input of the outer function.

Composition requires output-to-input type match.

g:: double -> double f:: double -> bool
Function f expects a single value, however g returns an array.

g:: int -> [int] f:: int -> bool
This problem can be solved with monads and Kleisli composition.
f(g(x))?f(x) = x2 - x - 1g(x) = x + 1x in f with the definition of g.
auto compose = [](auto f, auto g) {
return [=](auto x) {
return f(g(x));
};
};
auto op = compose(f2, f1);
Unary function composition only.
double fahrenheitToCelsius(double fahr){
return (fahr - 32) * 5.0 / 9.0;
}
bool isRoomTemperature(double t){
return (t >= 20.0 && t < 25.0) ? true : false;
}
Notice the order, we compose from right to left.

auto op = compose(isRoomTemperature, fahrenheitToCelsius); auto val1 = op(71.9); // returns 1, i.e. room temperature auto val2 = op(50.3); // returns 0, i.e. not room temperature
auto opComposed(double fahr){
return isRoomTemperature(fahreheitToCelsius(fahr));
}
int main() {
auto val = opComposed(71.9); // room temperature
}
auto vecBool = map(vecTemp,
compose(isRoomTemperature, fahrenheitToCelsius));
The composed function can be directly fed into higher-order functions, such as map and filter.
f(g(x)), then g(f(x))f(x) = 0.5x - 5g(x) = 2x + 10f • g ≠ g • f
The result happened to be the same, because the functions were mutual inverses.
double bmi(double weight, double height){
return weight / height / height;
}
bool isOverweight(double bmi){
return (bmi >= 25.0) ? true : false;
}
auto compose = [](auto f, auto g) {
return [=](auto&& ... x) {
return f(g(x...));
};
};

auto op = compose(isOverweight, bmi); auto val1 = op(59.8, 1.7); // returns 0, i.e. false auto val2 = op(73.0, 1.52); // returns 1, i.e. true
(f • g) • h = f • (g • h)
compose(compose(f,g),h)=compose(f,compose(g,h))
(f • g) • h and f • (g • h)?
f(x) = x - 2, g(x) = x2, h(x) = 2x,
Full application produces a value, partial application produces a function that "remembers" values.
Function composition