0
# Function Utilities
1
2
Core functional programming utilities including currying, function composition, argument manipulation, and memoization. The Function module provides 6 essential functions for higher-order programming patterns.
3
4
## Capabilities
5
6
### Function Transformation
7
8
Functions for transforming and adapting other functions.
9
10
```javascript { .api }
11
/**
12
* Applies function to array of arguments
13
* @param {Function} fn - Function to apply
14
* @param {Array} args - Array of arguments to pass to function
15
* @returns {*} Result of function application
16
*/
17
function apply(fn, args);
18
19
/**
20
* Converts function to curried version
21
* @param {Function} fn - Function to curry
22
* @returns {Function} Curried function supporting partial application
23
*/
24
function curry(fn);
25
26
/**
27
* Flips order of first two arguments of a function
28
* @param {Function} fn - Function with at least 2 parameters
29
* @param {*} x - Second argument
30
* @param {*} y - First argument
31
* @returns {*} Result of fn(y, x)
32
*/
33
function flip(fn, x, y);
34
35
/**
36
* Fixed-point combinator for recursive functions
37
* @param {Function} fn - Function that takes a recursive function as argument
38
* @returns {Function} Fixed-point function
39
*/
40
function fix(fn);
41
42
/**
43
* Applies function to results of another function on two values
44
* @param {Function} fn - Binary function
45
* @param {Function} gn - Function to apply to both arguments
46
* @param {*} x - First value
47
* @param {*} y - Second value
48
* @returns {*} Result of fn(gn(x), gn(y))
49
*/
50
function over(fn, gn, x, y);
51
52
/**
53
* Creates memoized version of function with caching
54
* @param {Function} fn - Function to memoize
55
* @returns {Function} Memoized function that caches results
56
*/
57
function memoize(fn);
58
```
59
60
## Usage Examples
61
62
**Function Application:**
63
64
```javascript
65
const { apply } = require('prelude-ls');
66
67
const add = (a, b, c) => a + b + c;
68
const args = [1, 2, 3];
69
70
const result = apply(add, args); // 6
71
// Equivalent to: add(1, 2, 3)
72
73
// Useful with Math functions
74
const numbers = [10, 5, 8, 3];
75
const max = apply(Math.max, numbers); // 10
76
const min = apply(Math.min, numbers); // 3
77
```
78
79
**Currying Functions:**
80
81
```javascript
82
const { curry } = require('prelude-ls');
83
84
const add = (a, b, c) => a + b + c;
85
const curriedAdd = curry(add);
86
87
// Partial application
88
const add5 = curriedAdd(5);
89
const add5and3 = add5(3);
90
const result = add5and3(2); // 10
91
92
// Can also be called normally
93
const result2 = curriedAdd(1, 2, 3); // 6
94
95
// Building reusable functions
96
const multiply = curry((a, b) => a * b);
97
const double = multiply(2);
98
const triple = multiply(3);
99
100
const doubled = [1, 2, 3].map(double); // [2, 4, 6]
101
const tripled = [1, 2, 3].map(triple); // [3, 6, 9]
102
```
103
104
**Argument Order Manipulation:**
105
106
```javascript
107
const { flip } = require('prelude-ls');
108
109
const subtract = (a, b) => a - b;
110
const flippedSubtract = flip(subtract);
111
112
const result1 = subtract(10, 3); // 7
113
const result2 = flippedSubtract(10, 3); // -7 (same as subtract(3, 10))
114
115
// Useful for creating readable functions
116
const divide = (a, b) => a / b;
117
const divideBy = flip(divide);
118
119
const halve = divideBy(2);
120
const quarter = divideBy(4);
121
122
const numbers = [8, 12, 16];
123
const halved = numbers.map(halve); // [4, 6, 8]
124
```
125
126
**Function Composition with Over:**
127
128
```javascript
129
const { over } = require('prelude-ls');
130
131
const add = (a, b) => a + b;
132
const square = x => x * x;
133
134
// Apply square to both arguments, then add
135
const addSquares = over(add, square);
136
137
const result = addSquares(3, 4); // 25 (3² + 4² = 9 + 16)
138
139
// Useful for comparisons
140
const compare = (a, b) => a - b;
141
const compareByLength = over(compare, str => str.length);
142
143
const strings = ['cat', 'elephant', 'dog'];
144
const sorted = strings.sort(compareByLength);
145
// Result: ['cat', 'dog', 'elephant']
146
```
147
148
**Recursive Functions with Fix:**
149
150
```javascript
151
const { fix } = require('prelude-ls');
152
153
// Factorial using fix-point combinator
154
const factorial = fix(rec => n => n <= 1 ? 1 : n * rec(n - 1));
155
156
const result1 = factorial(5); // 120
157
const result2 = factorial(0); // 1
158
159
// Fibonacci using fix-point combinator
160
const fibonacci = fix(rec => n => n <= 1 ? n : rec(n - 1) + rec(n - 2));
161
162
const result3 = fibonacci(10); // 55
163
164
// List processing with recursion
165
const sum = fix(rec => list =>
166
list.length === 0 ? 0 : list[0] + rec(list.slice(1)));
167
168
const result4 = sum([1, 2, 3, 4, 5]); // 15
169
```
170
171
**Function Memoization:**
172
173
```javascript
174
const { memoize } = require('prelude-ls');
175
176
// Expensive computation
177
const expensiveFunction = (n) => {
178
console.log(`Computing for ${n}`);
179
return n * n * n;
180
};
181
182
const memoizedFunction = memoize(expensiveFunction);
183
184
const result1 = memoizedFunction(5); // Logs "Computing for 5", returns 125
185
const result2 = memoizedFunction(5); // No log, returns cached 125
186
const result3 = memoizedFunction(3); // Logs "Computing for 3", returns 27
187
188
// Memoized recursive function (like Fibonacci)
189
const fibMemo = memoize(n => n <= 1 ? n : fibMemo(n - 1) + fibMemo(n - 2));
190
191
const result4 = fibMemo(40); // Much faster than naive recursion
192
```
193
194
**Complex Function Composition:**
195
196
```javascript
197
const { curry, flip, over, apply } = require('prelude-ls');
198
199
// Building a data processing pipeline
200
const map = curry((fn, array) => array.map(fn));
201
const filter = curry((predicate, array) => array.filter(predicate));
202
const reduce = curry((fn, initial, array) => array.reduce(fn, initial));
203
204
// Create reusable processors
205
const double = map(x => x * 2);
206
const evens = filter(x => x % 2 === 0);
207
const sum = reduce((a, b) => a + b, 0);
208
209
// Compose operations
210
const processNumbers = numbers => sum(evens(double(numbers)));
211
212
const result = processNumbers([1, 2, 3, 4, 5]); // 30
213
```
214
215
**Higher-Order Function Utilities:**
216
217
```javascript
218
const { curry, flip, over } = require('prelude-ls');
219
220
// Create a general comparison function
221
const compareBy = curry((fn, a, b) => {
222
const aVal = fn(a);
223
const bVal = fn(b);
224
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
225
});
226
227
// Sort by different criteria
228
const people = [
229
{ name: 'Alice', age: 30 },
230
{ name: 'Bob', age: 25 },
231
{ name: 'Charlie', age: 35 }
232
];
233
234
const byAge = compareBy(person => person.age);
235
const byName = compareBy(person => person.name);
236
237
const sortedByAge = people.sort(byAge);
238
const sortedByName = people.sort(byName);
239
```
240
241
**Partial Application Patterns:**
242
243
```javascript
244
const { curry, flip } = require('prelude-ls');
245
246
// Configuration-based functions
247
const request = curry((method, url, data) => {
248
// Simulate HTTP request
249
return `${method} ${url} with ${JSON.stringify(data)}`;
250
});
251
252
// Create method-specific functions
253
const get = request('GET');
254
const post = request('POST');
255
const put = request('PUT');
256
257
// Create endpoint-specific functions
258
const getUser = get('/api/users');
259
const postUser = post('/api/users');
260
261
const result1 = getUser({ id: 123 });
262
const result2 = postUser({ name: 'Alice', email: 'alice@example.com' });
263
```