@mattstyles/match v1.0.1
match
Pattern matching algorithm
Install
Install with npm
$ npm i -S @mattstyles/matchExample
const match = require('@mattstyles/match')Usage
Match implements a simple pattern matching mechanism, heavily inspired by Rust’s match keyword.
const match = require('@mattstyles/match')
const log = prefix => value => console.log(`${prefix}${value}`)
const matcher = match([
['FOO', log('::')],
['BAR', log('> ')]
])
matcher('FOO')
// ::FOO
matcher('BAR')
// > BARMatch can be used to simplify complex branching logic and if/then soup.
Matching on all the things
Match will attempt a strict equality check (===) on your match conditions which means that strings and integers are trivial to use, even matching on the same object is possible as match accepts an array of tuples of the form <any, function>.
const obj = {foo: 'bar'}
const matcher = match([
['FOO', log()],
[23, log()],
[obj, log()]
])
// Even this would match
matcher(obj)The wise will know that JS pattern matching capabilities and type system aren’t particularly helpful to our goal and the eagle eyed will notice that in the above example it will only match against the exact same object, not an instance that merely looks identical.
Thankfully JS isn’t totally hapless and many problems can be solved by the humble function (sometimes at the expense of brevity or clarity). Match can accept a predicate function to use as a match condition:
const deepEqual = require('deep-equal')
const equal = predicate => value => deepEqual(predicate, value)
const matcher = match([
[equal({foo: 'bar'}), log()]
])
matcher({
foo: 'bar'
})Rather than duck-typing you could go a step further with this and use instanceof checks if you really wanted:
const instance = struct => type => type instanceof struct
class Foo {}
const matcher = match([
[instance(Foo), log()]
])
matcher(new Foo())Exhaustive matching
JS can’t work out if you’ve supplied enough conditions to be exhaustive but match will accept a lone function to use as a catch-all:
const matcher = match([
['foo', log('::')],
[log('Caught it: ')]
])
matcher('foo')
// ::foo
matcher('bar')
// Caught it: barAssignment
Match will spit out whatever the conditional functions return and so can also be used for assignment:
const matcher = match([
[10, 'the same as']
[v => v < 10, 'lower than'],
[v => v > 10, 'higher than']
])
const return = match(4)
console.log(`4 is ${return} 10`)
// 4 is lower than 10Running tests
$ npm install
$ npm testContributing
Pull requests are always welcome, the project uses the standard code style. Please run npm test to ensure all tests are passing and add tests for any new features or updates.
For bugs and feature requests, please create an issue.
License
MIT