Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
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'
gradeExam(25), // -> 'excellent'
)
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"
)
* @param {object} data
* @param {string} format
* @returns {void}
*/
const save = multi(
(data, format) => format, // Custom dispatch function
method('json', (data, format) => {
console.log('Saving as JSON!')
}),
method('html', (data, format) => {
console.log('Saving as HTML!')
}),
method((data, format) => {
console.log('Default - saving as TXT!')
}),
)
const data = { name: 'Alice', score: 100 }
save(data, 'json') // -> "Saving as JSON!"
save(data, 'html') // -> "Saving as HTML!"
save(data, 'csv') // -> "Default - saving as TXT!"
const extendedSave = method('csv', (data, format) => {
console.log('Saving as CSV!')
})(save)
extendedSave(data, 'json') // -> "Saving as JSON!"
extendedSave(data, 'html') // -> "Saving as HTML!"
* matched using the constructor algorithm, other values of the array
* will be matched using a deep strict equal algorithm.
*
* The algorithm, by design, checks for constructors only the first-level array.
*
* It can be very useful, for example as a trivial alternative
* to otherwise complex visitor patter.
*
* @param {Object} document
* @param {Object} template
* @returns {string} embedding description
*/
const embed = multi(
method([Article, PDF], 'Embedding article inside PDF'),
method([Article, HTML], 'Embedding article inside HTML'),
method([Recipe, PDF], 'Embedding recipe inside PDF'),
method([Recipe, HTML], 'Embedding recipe inside HTML'),
)
console.log(
embed(new Article(), new PDF()), // -> "Embedding article inside PDF"
embed(new Recipe(), new HTML()), // -> "Embedding recipe inside HTML"
)
/**
* 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 { 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 extendedSave = method('csv', (data, format) => {
console.log('Saving as CSV!')
})(save)
extendedSave(data, 'json') // -> "Saving as JSON!"
extendedSave(data, 'html') // -> "Saving as HTML!"
extendedSave(data, 'csv') // -> "Saving as CSV!"
extendedSave(data, 'yaml') // -> "Default - saving as TXT!"
const extendedSave2 = fromMulti(
method('csv', (data, format) => {
console.log('Saving as CSV!')
}),
method('yaml', (data, format) => {
console.log('Saving as YAML!')
}),
)(save)
extendedSave2(data, 'json') // -> "Saving as JSON!"
extendedSave2(data, 'html') // -> "Saving as HTML!"
extendedSave2(data, 'csv') // -> "Saving as CSV!"
extendedSave2(data, 'yaml') // -> "Saving as YAML!"
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"
)
import { method, multi, Multi } from '@arrows/multimethod'
/**
* Multimethod type defined using interface.
*
* Extending `Multi` type guarantees that the multimethod will
* be recognized correctly when extended by `fromMulti` function.
*/
interface IMultiply extends Multi {
(times: number, x: number): number
(times: number, x: string): string
}
const multiply: IMultiply = multi(
(times: number, x: any): string => typeof x,
method('number', (times: number, x: number): number => x * times),
method('string', (times: number, x: string): string => x.repeat(times)),
)
console.log(
multiply(3, 3), // -> 9
multiply(3, 'foo'), // -> "foofoofoo"
// multiply(3, [1, 2, 3]), // compiler error
)
export { IMultiply }
export default multiply
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"