Skip to content

Instantly share code, notes, and snippets.

@mjgpy3
Created March 7, 2016 18:25
Show Gist options
  • Save mjgpy3/21141f47c43ef149e0f7 to your computer and use it in GitHub Desktop.
Save mjgpy3/21141f47c43ef149e0f7 to your computer and use it in GitHub Desktop.
Easy pattern matching in JavaScript
'use strict';
const buildMatcher = (cases) => (actual) =>
cases
.find((cse) => cse.matches(actual))
.result(actual);
const buildNextOn = (previousCases) => {
var build = (matchesPred, result) => {
const cases = previousCases.concat(
[
{
matches: matchesPred,
result: result
}
]
);
return {
match: buildMatcher(cases),
on: buildNextOn(cases)
};
};
return {
value: (v, result) => build(
(actual) => actual === v,
result
),
anything: (result) => build(
(_) => true,
result
),
object: {
withProperties: (properties, result) => build(
(value) => properties.every((prop) => prop in value),
result
)
}
};
};
const on = buildNextOn([]);
console.log(
on.value(35, () => 27).
on.value(42, () => 35).
match(42)
);
// => 35
var fn = on.value(35, () => 27).on.value(42, () => 35).match;
console.log(fn(35));
// => 27
var factorial =
on.value(1, () => 1).
on.anything((n) => n * factorial(n - 1)).
match;
console.log(factorial(4));
// => 24
var objectMatcher =
on.object.withProperties(['a', 'b'], (obj) => obj.b).
on.object.withProperties(['a', 'c'], (obj) => obj.c).
on.anything((_) => { return { not: 'matched' } }).
match;
console.log(objectMatcher({ a: 'foo', c: 'bar' }));
// => 'bar'
console.log(objectMatcher({}));
// => { not: 'matched' }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment