function vectorAdd(v1, v2) {
return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]];
}
vectorAdd([1, 2, 3], [4, 5, 6]);
vectorAdd([1, 2, 3, 4], [5, 6, 7]);
vectorAdd('foo', 'bar');
function vectorAdd(v1, v2) {
throwOnArrayMismatch(v1);
throwOnArrayMismatch(v2);
return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]];
}
vectorAdd([1, 2, 3], [4, 5, 6]);
vectorAdd([1, 2, 3, 4], [5, 6, 7]);
vectorAdd('foo', 'bar');
vectorAdd.signature = 'array, array => array';
function vectorAdd(v1, v2) {
throwOnArrayMismatch(v1);
throwOnArrayMismatch(v2);
return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]];
}
(function (fn) { return fn.signature})(vectorAdd);
vectorAdd([1, 2, 3], [4, 5, 6]);
vectorAdd([1, 2, 3, 4], [5, 6, 7]);
vectorAdd('foo', 'bar');
var vectorAdd = signet.enforce(
'array, array => array',
function vectorAdd(v1, v2) {
return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]];
});
(function (fn) { return fn.signature })(vectorAdd);
vectorAdd([1, 2, 3], [4, 5, 6]);
vectorAdd([1, 2, 3, 4], [5, 6, 7]);
vectorAdd('foo', 'bar');
φ is defined as follows:
A type set can be defined with a predicate function
This rises from the Curry-Howard Isomorphism
function checkType(type, value) {
if (!signet.isTypeOf(type)(value)) {
var errorMessage = 'Expected value of type ' +
type + ' but got ' +
typeof value + ' (' +
value.toString() + ')';
throw new Error(errorMessage);
}
return value.toString() + ' is of type ' + type;
}
function lowerCaseType (value){
return typeof value === 'string' && value.toLowerCase() === value;
}
signet.extend('lowerCase', lowerCaseType);
checkType('lowerCase', 'foo'),
checkType('lowerCase', 'bar'),
checkType('lowerCase', 'BaZ'),
A subtype can be defined as a subset of another type
number -> int -> natural -> age
signet.subtype('number')('int', value => value === Math.floor(value));
signet.subtype('int')('natural', value => value >= 0;);
signet.subtype('natural')('age', value => value <= 150;);
checkType('int', 3.2);
checkType('int', -3);
checkType('natural', -3);
checkType('natural', 200);
checkType('age', 200);
checkType('age', 42);
function checkType (tuple, type, index){
return signet.isTypeOf(type)(tuple[index]);
}
function verifyTuple (tuple, typeObj) {
return typeObj.valueType
.map(checkType.bind(null, tuple))
.reduce(function (a, b) { return a && b; }, true);
}
signet.subtype('array')('tuple', tupleType);
function tupleType(tuple, typeObj) {
var correctLength = tuple.length === typeObj.valueType.length;
var correctTypes = verifyTuple(tuple, typeObj);
return correctLength && correctTypes;
}
signet.subtype('string')('name', function (value) {
return value.length < 20;
});
checkType('tuple<number;number>', [3, 4]),
checkType('tuple<age;name>', [21, 'Bobby']),
checkType('tuple<age;name>', [5, 99])
signet.subtype('string')('formattedString', function (value, typeObj) {
var pattern = new RegExp(typeObj.valueType[0]);
return value.match(pattern) !== null;
});
var ssnPattern = '^[0-9]{3}\\-[0-9]{2}\\-[0-9]{4}$';
var ssnDefinition = 'formattedString<' + ssnPattern + '>';
signet.alias('ssn', ssnDefinition);
checkType('ssn', '123-45-6789');
checkType('ssn', '123456789');
checkType('ssn', 'FOO');
signet.alias('3dVector', 'tuple<number;number;number>');
var vectorAdd = signet.enforce(
'3dVector, 3dVector => 3dVector',
function vectorAdd(v1, v2) {
return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]];
});
vectorAdd([1, 2, 3], [4, 5, 6]);
vectorAdd([1, 2, 3, 4], [5, 6, 7]);
vectorAdd('foo', 'bar');