UNPKG

crocks

Version:

A collection of well known Algebraic Datatypes for your utter enjoyment.

64 lines (48 loc) 1.79 kB
/** @license ISC License (c) copyright 2016 original and current authors */ /** @author Ian Hofmann-Hicks (evil) */ var curry = require('./curry') var isArray = require('./isArray') var isEmpty = require('./isEmpty') var isFunction = require('./isFunction') var isObject = require('./isObject') var isString = require('./isString') var constant = function (x) { return function () { return x; }; } var isDefinition = function (x) { return isString(x) && x.length; } function caseOf(defs) { return function(cases, m) { var tag = m.tag var def = defs[tag()] var args = def.reduce( function (xs, x) { return xs.concat([ m[x].value() ]); }, [] ) return cases[tag()].apply(null, args) } } var includes = function (defs) { return function (m) { return !!m && isFunction(m.tag) && Object.keys(defs).indexOf(m.tag()) !== -1; }; } function construction(def, tag) { return function() { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return def.reduce(function(obj, key, index) { obj[key] = { value: constant(args[index]) } return obj }, { tag: constant(tag) }) } } function defineUnion(defs) { if(!isObject(defs) || isEmpty(defs)) { throw new TypeError('defineUnion: Argument must be an Object containing definition lists') } return Object.keys(defs).reduce(function(obj, tag) { var def = defs[tag] if(!isArray(def) || !def.reduce(function (x, y) { return x && isDefinition(y); }, true)) { throw new TypeError('defineUnion: Definitions must be a list of non-empty string identifiers') } obj[tag] = construction(def, tag) return obj }, { caseOf: curry(caseOf(defs)), includes: curry(includes(defs)) }) } module.exports = defineUnion