UNPKG

wecui

Version:

一款基于Vue2.x版本的移动端web组件

114 lines (87 loc) 3.65 kB
var assert = require('./assert'); var isTypeName = require('./isTypeName'); var FunctionType = require('./Function'); var isArray = require('./isArray'); var list = require('./list'); var isObject = require('./isObject'); var create = require('./create'); var isNil = require('./isNil'); var isBoolean = require('./isBoolean'); var tuple = require('./tuple'); var getFunctionName = require('./getFunctionName'); var getTypeName = require('./getTypeName'); function getDefaultName(domain, codomain) { return '(' + domain.map(getTypeName).join(', ') + ') => ' + getTypeName(codomain); } function isInstrumented(f) { return FunctionType.is(f) && isObject(f.instrumentation); } function func(domain, codomain, name) { domain = isArray(domain) ? domain : [domain]; // handle handy syntax for unary functions if (process.env.NODE_ENV !== 'production') { assert(list(FunctionType).is(domain), function () { return 'Invalid argument domain ' + assert.stringify(domain) + ' supplied to func(domain, codomain, [name]) combinator (expected an array of types)'; }); assert(FunctionType.is(codomain), function () { return 'Invalid argument codomain ' + assert.stringify(codomain) + ' supplied to func(domain, codomain, [name]) combinator (expected a type)'; }); assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to func(domain, codomain, [name]) combinator (expected a string)'; }); } var displayName = name || getDefaultName(domain, codomain); function FuncType(value, curried) { if (!isInstrumented(value)) { // automatically instrument the function return FuncType.of(value, curried); } if (process.env.NODE_ENV !== 'production') { assert(FuncType.is(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + displayName; }); } return value; } FuncType.meta = { kind: 'func', domain: domain, codomain: codomain, name: name, identity: true }; FuncType.displayName = displayName; FuncType.is = function (x) { return isInstrumented(x) && x.instrumentation.domain.length === domain.length && x.instrumentation.domain.every(function (type, i) { return type === domain[i]; }) && x.instrumentation.codomain === codomain; }; FuncType.of = function (f, curried) { if (process.env.NODE_ENV !== 'production') { assert(FunctionType.is(f), function () { return 'Invalid argument f supplied to func.of ' + displayName + ' (expected a function)'; }); assert(isNil(curried) || isBoolean(curried), function () { return 'Invalid argument curried ' + assert.stringify(curried) + ' supplied to func.of ' + displayName + ' (expected a boolean)'; }); } if (FuncType.is(f)) { // makes FuncType.of idempotent return f; } function fn() { var args = Array.prototype.slice.call(arguments); var len = curried ? args.length : domain.length; var argsType = tuple(domain.slice(0, len)); args = argsType(args); // type check arguments if (len === domain.length) { return create(codomain, f.apply(this, args)); } else { var g = Function.prototype.bind.apply(f, [this].concat(args)); var newdomain = func(domain.slice(len), codomain); return newdomain.of(g, curried); } } fn.instrumentation = { domain: domain, codomain: codomain, f: f }; fn.displayName = getFunctionName(f); return fn; }; return FuncType; } func.getDefaultName = getDefaultName; module.exports = func;