I'm learning functional programming and I wonder if there is a way to "combine" functions like this:
function triple(x) {
return x * 3;
}
function plusOne(x) {
return x + 1;
}
function isZero(x) {
return x === 0;
}
combine(1); //1
combine(triple)(triple)(plusOne)(1); // 10
combine(plusOne)(triple)(isZero)(-1); // true
If the para is a function, it "combines" the function into itself, and if not it will return the final result. Thanks!
You can't 'merge' functions as you describe them there, but what you can do is have one function be redefined to call both itself and a new function (before or after the original). var xyz = function(){ console. log('xyz'); }; var abc = function(){ console.
Functional programming is a paradigm of building computer programs using expressions and functions without mutating state and data. By respecting these restrictions, functional programming aims to write code that is clearer to understand and more bug resistant.
Function composition is an approach where the result of one function is passed on to the next function, which is passed to another until the final function is executed for the final result. Function compositions can be composed of any number of functions.
There are 3 ways of writing a function in JavaScript: Function Declaration. Function Expression. Arrow Function.
heritage
This is a concept from maths called function composition.
f(x) = y
g(y) = z
g(f(x)) = z
(g•f)(x) = z
That last line is read "g of f of x equals z". What's great about composed functions is the elimination of points. Notice in g(f(x)) = z
we take an x
input and get a z
output. This skips the intermediate point, y
.
Composition is a great way to create higher-order functions and keep your code sparkly clean. It's plain to see why we'd want this in our Javascript programs.
comp
JavaScript is a multi-paradigm language with rich support for functions. We can create a simple comp
function, which combines two input functions, g
and f
, and results in a new function -
function triple(x) {
return x * 3
}
function plusOne(x) {
return x + 1
}
function comp(g, f) {
return function(x) {
return g(f(x)) // "g of f of x"
}
}
const myfunc =
comp(triple, plusOne)
console.log(myfunc(1))
Evaluation
triple(plusOne(1))
triple(2)
6
compose
Just as the question suggests, it's likely we will want to combine more than two functions. Below we write compose
which takes all
of the input functions and reduce
s them using our simple comp
from above. If no functions are given, we return the empty function, identity
-
const triple = (x) =>
x * 3
const plusOne = (x) =>
x + 1
const comp = (g, f) =>
x => g(f(x)) // "g of f of x"
const identity = (x) =>
x
const compose = (...all) =>
all.reduce(comp, identity)
const myfunc =
compose(triple, triple, plusOne) // any amount of funcs
console.log(myfunc(1))
Evaluation
triple(triple(plusOne(1)))
triple(triple(2))
triple(6)
18
pipe
You can be as creative as you like. Below, we write pipe
which allows our programs to read in a comfortable left-to-right direction -
const triple = (x) =>
x * 3
const plusOne = (x) =>
x + 1
const pipe = x =>
f => pipe(f(x))
pipe(1)(plusOne)(triple)(triple)(console.log) // 18
pipe(3)(triple)(plusOne)(triple)(plusOne)(console.log) // 31
Evaluation of expression one -
f => pipe(f(1))
pipe(plusOne(1))
f => pipe(f(2))
pipe(triple(2))
f => pipe(f(6))
pipe(triple(6))
f => pipe(f(18))
pipe(console.log(18))
18
and expression two -
f => pipe(f(3))
pipe(triple(3))
f => pipe(f(9))
pipe(plusOne(9))
f => pipe(f(10))
pipe(triple(10))
f => pipe(f(30))
pipe(plusOne(31))
f => pipe(f(31))
pipe(console.log(31))
31
related techniques
Curried functions and partial application are concepts that gel with function composition. pipe
above is introduced in another Q&A as $
and demonstrated again here -
const $ = x => // "pipe", or whatever name you pick
k => $ (k (x))
const add = x => y => // curried add
x + y
const mult = x => y => // curried mult
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With