Last active
June 27, 2019 15:16
-
-
Save oncomouse/25c3dfc3aecf0aa568e5ade53cece4cb to your computer and use it in GitHub Desktop.
Pattern matching (matchWith) for Crocks ADTs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const compose = require('crocks/helpers/compose'); | |
const curry = require('crocks/helpers/curry'); | |
// head :: [a] -> a | |
const head = xs => xs[0]; | |
// split :: String -> String -> [String] | |
const split = curry((s, xs) => xs.split(s)); | |
// toString :: a -> String | |
const toString = m => m.toString(); | |
// has :: a -> Object -> Boolean | |
const has = curry((key, obj) => Object.prototype.hasOwnProperty.call(obj, key)); | |
// getType :: Union a => a -> String | |
const getType = compose(head, split(' '), toString); | |
const ANY = 'ANY'; | |
// matchWith :: Union a => {String: (b -> *)} -> a b -> * | |
const matchWith = curry((defs, value) => { | |
const type = getType(value); | |
if (has(type, defs)) { | |
return defs[type](value); | |
} else if (has(ANY, defs)) { | |
return defs[ANY](value); | |
} else { | |
throw new Error(`Could not find a match for ${value} in the provided defs (${Object.keys(defs).join(', ')}). | |
If you want a default to run, please import ANY from this file and add that to the object of definitions passed to matchWith.`); | |
} | |
}); | |
// Handle exports: | |
matchWith.ANY = ANY; | |
module.exports = matchWith; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment