Хорошо, первый фрагмент покажет вам, как это сделать с Vanilla JS:
const compose = (points, fns) => {
let output = points;
points.map( (p,i) => {
fns.map( fn => output[i] = fn(output[i]) );
});
return output;
}
const funA = ({x,y}) => ({x: x*2, y: y*2});
const funB = ({x,y}) => ({x: x*2, y: y*2});
const sqrt = ({x,y}) => ({x: Math.sqrt(x), y: Math.sqrt(y)});
const points = [{x:1, y:1}, {x:2, y:2}];
const res = compose(points, [funA, funB, sqrt]); // sqrt(funB(funA(points))) = funA ¤ funB ¤ sqrt
console.log(res);
А теперь с библиотекой, предназначенной для составления функций (ramda.js):
const funA = ({x,y}) => ({x: x*2, y: y*2});
const funB = ({x,y}) => ({x: x*2, y: y*2});
const sqrt = ({x,y}) => ({x: Math.sqrt(x), y: Math.sqrt(y)});
const points = [{x:1, y:1}, {x:2, y:2}];
const curryFun = R.compose(sqrt, funA, funB);
const resCurry = points.map( curryFun );
console.log(resCurry);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js" integrity="sha256-43x9r7YRdZpZqTjDT5E0Vfrxn1ajIZLyYWtfAXsargA=" crossorigin="anonymous"></script>
ПРАКТИЧЕСКИЙ EG:
Здесь я приведу, например, о двухмерных функциях, у нас есть линейная область абсциска, и мы хотим построить составной fn:
// declare fn
const lin = x => x * 1.2 + 0.9;
const sin = x => Math.sin(x);
const cos = x => Math.cos(x);
// set the linspace
const linspace = [...new Array(50)].map((val,i) => i/10 );
// set the composed fn
const composed = R.compose(lin, sin, cos);
// we can write : composed = R.compose(lin, Math.sin, Math.cos)
// graph
var ctx = document.getElementById("myChart");
var data = {
labels: linspace,
datasets: [{
label: "lin",
function: lin,
borderColor: "rgba(75, 192, 192, 1)",
data: [],
fill: false
},
{
label: "sin",
function: sin,
borderColor: "rgba(153, 102, 255, 1)",
data: [],
fill: false
},
{
label: "cos",
function: cos,
borderColor: "rgba(255, 206, 86, 1)",
data: [],
fill: false
},
{
label: "composed",
function: composed,
borderColor: "rgba(255, 106, 86, 1)",
data: [],
fill: false
}
]
};
Chart.pluginService.register({
beforeInit: function(chart) {
var data = chart.config.data;
for (var i = 0; i < data.datasets.length; i++) {
for (var j = 0; j < data.labels.length; j++) {
var fct = data.datasets[i].function,
x = data.labels[j],
y = fct(x);
data.datasets[i].data.push(y);
}
}
}
});
var myBarChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js" integrity="sha256-43x9r7YRdZpZqTjDT5E0Vfrxn1ajIZLyYWtfAXsargA=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" integrity="sha256-Uv9BNBucvCPipKQ2NS9wYpJmi8DTOEfTA/nH2aoJALw=" crossorigin="anonymous"></script>
<canvas id="myChart"></canvas>