CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-prelude-ls

A functionally oriented utility library for LiveScript with curried functions for lists, objects, strings, numbers, and function composition.

89

1.53x
Overview
Eval results
Files

function-utilities.mddocs/

Function Utilities

Core functional programming utilities including currying, function composition, argument manipulation, and memoization. The Function module provides 6 essential functions for higher-order programming patterns.

Capabilities

Function Transformation

Functions for transforming and adapting other functions.

/**
 * Applies function to array of arguments
 * @param {Function} fn - Function to apply
 * @param {Array} args - Array of arguments to pass to function
 * @returns {*} Result of function application
 */
function apply(fn, args);

/**
 * Converts function to curried version
 * @param {Function} fn - Function to curry
 * @returns {Function} Curried function supporting partial application
 */
function curry(fn);

/**
 * Flips order of first two arguments of a function
 * @param {Function} fn - Function with at least 2 parameters
 * @param {*} x - Second argument
 * @param {*} y - First argument
 * @returns {*} Result of fn(y, x)
 */
function flip(fn, x, y);

/**
 * Fixed-point combinator for recursive functions
 * @param {Function} fn - Function that takes a recursive function as argument
 * @returns {Function} Fixed-point function
 */
function fix(fn);

/**
 * Applies function to results of another function on two values
 * @param {Function} fn - Binary function
 * @param {Function} gn - Function to apply to both arguments
 * @param {*} x - First value
 * @param {*} y - Second value
 * @returns {*} Result of fn(gn(x), gn(y))
 */
function over(fn, gn, x, y);

/**
 * Creates memoized version of function with caching
 * @param {Function} fn - Function to memoize
 * @returns {Function} Memoized function that caches results
 */
function memoize(fn);

Usage Examples

Function Application:

const { apply } = require('prelude-ls');

const add = (a, b, c) => a + b + c;
const args = [1, 2, 3];

const result = apply(add, args);          // 6
// Equivalent to: add(1, 2, 3)

// Useful with Math functions
const numbers = [10, 5, 8, 3];
const max = apply(Math.max, numbers);     // 10
const min = apply(Math.min, numbers);     // 3

Currying Functions:

const { curry } = require('prelude-ls');

const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);

// Partial application
const add5 = curriedAdd(5);
const add5and3 = add5(3);
const result = add5and3(2);               // 10

// Can also be called normally
const result2 = curriedAdd(1, 2, 3);      // 6

// Building reusable functions
const multiply = curry((a, b) => a * b);
const double = multiply(2);
const triple = multiply(3);

const doubled = [1, 2, 3].map(double);    // [2, 4, 6]
const tripled = [1, 2, 3].map(triple);    // [3, 6, 9]

Argument Order Manipulation:

const { flip } = require('prelude-ls');

const subtract = (a, b) => a - b;
const flippedSubtract = flip(subtract);

const result1 = subtract(10, 3);          // 7
const result2 = flippedSubtract(10, 3);   // -7 (same as subtract(3, 10))

// Useful for creating readable functions
const divide = (a, b) => a / b;
const divideBy = flip(divide);

const halve = divideBy(2);
const quarter = divideBy(4);

const numbers = [8, 12, 16];
const halved = numbers.map(halve);        // [4, 6, 8]

Function Composition with Over:

const { over } = require('prelude-ls');

const add = (a, b) => a + b;
const square = x => x * x;

// Apply square to both arguments, then add
const addSquares = over(add, square);

const result = addSquares(3, 4);          // 25 (3² + 4² = 9 + 16)

// Useful for comparisons
const compare = (a, b) => a - b;
const compareByLength = over(compare, str => str.length);

const strings = ['cat', 'elephant', 'dog'];
const sorted = strings.sort(compareByLength);
// Result: ['cat', 'dog', 'elephant']

Recursive Functions with Fix:

const { fix } = require('prelude-ls');

// Factorial using fix-point combinator
const factorial = fix(rec => n => n <= 1 ? 1 : n * rec(n - 1));

const result1 = factorial(5);             // 120
const result2 = factorial(0);             // 1

// Fibonacci using fix-point combinator
const fibonacci = fix(rec => n => n <= 1 ? n : rec(n - 1) + rec(n - 2));

const result3 = fibonacci(10);            // 55

// List processing with recursion
const sum = fix(rec => list => 
  list.length === 0 ? 0 : list[0] + rec(list.slice(1)));

const result4 = sum([1, 2, 3, 4, 5]);    // 15

Function Memoization:

const { memoize } = require('prelude-ls');

// Expensive computation
const expensiveFunction = (n) => {
  console.log(`Computing for ${n}`);
  return n * n * n;
};

const memoizedFunction = memoize(expensiveFunction);

const result1 = memoizedFunction(5);      // Logs "Computing for 5", returns 125
const result2 = memoizedFunction(5);      // No log, returns cached 125
const result3 = memoizedFunction(3);      // Logs "Computing for 3", returns 27

// Memoized recursive function (like Fibonacci)
const fibMemo = memoize(n => n <= 1 ? n : fibMemo(n - 1) + fibMemo(n - 2));

const result4 = fibMemo(40);              // Much faster than naive recursion

Complex Function Composition:

const { curry, flip, over, apply } = require('prelude-ls');

// Building a data processing pipeline
const map = curry((fn, array) => array.map(fn));
const filter = curry((predicate, array) => array.filter(predicate));
const reduce = curry((fn, initial, array) => array.reduce(fn, initial));

// Create reusable processors
const double = map(x => x * 2);
const evens = filter(x => x % 2 === 0);
const sum = reduce((a, b) => a + b, 0);

// Compose operations
const processNumbers = numbers => sum(evens(double(numbers)));

const result = processNumbers([1, 2, 3, 4, 5]); // 30

Higher-Order Function Utilities:

const { curry, flip, over } = require('prelude-ls');

// Create a general comparison function
const compareBy = curry((fn, a, b) => {
  const aVal = fn(a);
  const bVal = fn(b);
  return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
});

// Sort by different criteria
const people = [
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25 },
  { name: 'Charlie', age: 35 }
];

const byAge = compareBy(person => person.age);
const byName = compareBy(person => person.name);

const sortedByAge = people.sort(byAge);
const sortedByName = people.sort(byName);

Partial Application Patterns:

const { curry, flip } = require('prelude-ls');

// Configuration-based functions
const request = curry((method, url, data) => {
  // Simulate HTTP request
  return `${method} ${url} with ${JSON.stringify(data)}`;
});

// Create method-specific functions
const get = request('GET');
const post = request('POST');
const put = request('PUT');

// Create endpoint-specific functions
const getUser = get('/api/users');
const postUser = post('/api/users');

const result1 = getUser({ id: 123 });
const result2 = postUser({ name: 'Alice', email: 'alice@example.com' });

Install with Tessl CLI

npx tessl i tessl/npm-prelude-ls

docs

function-utilities.md

index.md

list-operations.md

mathematical-operations.md

object-operations.md

string-processing.md

tile.json