Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
console.log('todo removed')
},
toggle(id) {
console.log('todo toggled')
},
}
/**
* Function with a custom dispatch.
* Dispatch function can produce any arbitrary value.
*
* @param {Object} action
* @param {Object} store
* @returns {void}
*/
const handleAction = multi(
(action, store) => action.type, // custom dispatch
method('ADD_TODO', (action, store) => store.add(action.text)),
method('REMOVE_TODO', (action, store) => store.remove(action.id)),
method('TOGGLE_TODO', (action, store) => store.toggle(action.id)),
)
handleAction({ type: 'ADD_TODO', text: 'Eat banana.' }, store) // -> "todo added"
handleAction({ type: 'TOGGLE_TODO', id: 0 }, store) // -> "todo toggled"
const { multi, method } = require('@arrows/multimethod')
/**
* Function with a single argument,
* default dispatch will return that argument as-is.
*
* @param {string} color
* @returns {string} hex color
*/
const colorToHex = multi(
method('red', '#ff0000'),
method('green', '#00ff00'),
method('blue', '#0000ff'),
)
console.log(
colorToHex('green'), // -> "#00ff00"
)
const { multi, method } = require('@arrows/multimethod')
const mapArray = (fn) => (arr) => arr.map(fn)
const mapString = (fn) => (str) => [...str].map(fn)
/**
* Manually curried function - each chunk has one argument.
*/
const map = multi(
(fn) => (val) => (Array.isArray(val) ? 'array' : typeof val),
method('array', mapArray),
method('string', mapString),
)
console.log(
map((char) => char.charCodeAt(0))('Hello'), // -> []
map((item) => item * 2)([1, 2, 3]), // -> [2, 4, 6]
)
const { multi, method } = require('@arrows/multimethod')
/**
* Function with a custom dispatch.
* More flexible version of the previous example.
*
* @param {string} colorA
* @param {string} colorB
* @returns {string} the resulting color
*/
const mixLights = multi(
(colorA, colorB) => [colorA, colorB].sort(), // custom dispatch
method(['green', 'red'], 'yellow'),
method(['blue', 'red'], 'magenta'),
method(['blue', 'green'], 'cyan'),
)
console.log(
mixLights('red', 'blue'), // -> "magenta"
mixLights('blue', 'red'), // -> "magenta"
)
const { multi, method, fromMulti } = require('@arrows/multimethod')
const baseArea = multi(
(shape) => shape.type,
method('rectangle', (shape) => shape.a * shape.b),
method('square', (shape) => shape.a ** 2),
)
/**
* Creating a new multimethod with many new methods via `fromMulti` function
*/
const area = fromMulti(
method('circle', (shape) => Math.PI * shape.r ** 2),
method('triangle', (shape) => 0.5 * shape.a * shape.h),
)(baseArea)
console.log(
area({ type: 'square', a: 5 }), // -> 25
area({ type: 'circle', r: 3 }), // -> 28.274333882308138
const { multi, method, fromMulti } = require('@arrows/multimethod')
/**
* Function where the priority does matter
*
* @param {number} points
* @returns {number} grade
*/
const baseGradeExam = multi(
method((points) => points < 10, 'failed'),
method((points) => points <= 15, 'ok'),
method((points) => points > 15, 'good'),
)
const gradeExam = fromMulti(
method((points) => points === 0, 'terrible'),
method((points) => points > 20, 'excellent'),
)(baseGradeExam)
console.log(
gradeExam(0), // -> 'terrible'
gradeExam(5), // -> 'failed'
gradeExam(10), // -> 'ok'
gradeExam(15), // -> 'ok'
gradeExam(20), // -> 'good'
/**
* Function with multiple arguments,
* default dispatch will return the array of arguments.
*
* Note that the order of the arguments does matter,
* so if you want the example to work for each combination,
* you either have to provide methods for reversed arguments
* or add your custom dispatch function,
* which returns sorted values (better option).
*
* @param {string} colorA
* @param {string} colorB
* @returns {string} the resulting color
*/
const mixLights = multi(
method(['red', 'green'], 'yellow'),
method(['red', 'blue'], 'magenta'),
method(['green', 'blue'], 'cyan'),
)
console.log(
mixLights('red', 'blue'), // -> "magenta"
// mixLights('blue', 'red'), // -> throws an error
)
const { curry } = require('@arrows/composition')
const { multi, method } = require('@arrows/multimethod')
/**
* Currying with a generic `curry` function.
* Explicit dispatch function (length: 2).
*
* Note that you can still use non-functions as corresponding values.
*
* @param {string} type
* @param {string} source
* @returns {string} info
*/
const play = multi(
(type, source) => type,
method('audio', (type, source) => `Playing audio from: ${source}`),
method('video', (type, source) => `Playing video from: ${source}`),
)
const curriedPlay = curry(play)
const playAudio = curriedPlay('audio')
const playVideo = curriedPlay('video')
console.log(
playAudio('songs.io/123'), // -> "Playing audio from: songs.io/123"
playVideo('movies.com/123'), // -> "Playing video from: movies.com/123"
)
const { multi, method } = require('@arrows/multimethod')
/**
* Function with case values as ordinary values.
* Values can be any JSON-compatible, arbitrary nested structure, or primitive.
* Matched by the deep strict equal algorithm.
*
* @param {Object} player
* @returns {string} greeting
*/
const greet = multi(
method({ name: 'John', age: '30' }, 'Hello John!'),
method({ name: 'Jane', age: '25' }, 'Hi Jane!'),
method('Howdy stranger!'),
)
console.log(
greet({ name: 'John', age: '30' }), // -> "Hello John!"
greet({ name: 'Jane', age: '25' }), // -> "Hi Jane!"
greet({ name: 'Jane', age: '40' }), // -> "Howdy stranger!"
)
const { multi, method } = require('@arrows/multimethod')
const baseAdd = multi(
(a, b) => [typeof a, typeof b],
method(['number', 'number'], (a, b) => a + b),
method(['string', 'string'], (a, b) => `${a}${b}`),
)
/**
* Creating a new multimethod with an additional method
*/
const add = method(['bigint', 'bigint'], (a, b) => a + b)(baseAdd)
console.log(
add(1, 2), // -> 3
add('bat', 'man'), // -> "batman"
// @ts-ignore
add(1n, 2n), // -> 3n
)