Skip to content

Instantly share code, notes, and snippets.

@BLamy
Last active October 31, 2016 00:43
Show Gist options
  • Save BLamy/acb4d6dabc07a1473a48c23fc99377f1 to your computer and use it in GitHub Desktop.
Save BLamy/acb4d6dabc07a1473a48c23fc99377f1 to your computer and use it in GitHub Desktop.
Ramda Where Types
const { where, equals, gt, is, pipe, __, curry, tryCatch, either } = require('ramda');
const enforceType = curry((pred, obj) => {
if (pred(obj)) return obj;
throw new Error();
});
const catchTypeError = tryCatch(__, (err, obj) => void 0);
const gaurdedFn = (typePredicate, fn) => catchTypeError(
pipe(enforceType(typePredicate), fn)
);
const userType = where({
firstName: is(String),
lastName: is(String),
age: is(Number),
sex: either(equals('M'), equals('F'))
});
const watchVideo = gaurdedFn(
userType,
curry((user, website) => Object.assign({}, user, { video: website }))
);
const isAdult = where({ age: gt(__, 18) });
const watchAdultVideo = gaurdedFn(
pipe(enforceType(userType), enforceType(isAdult)),
curry((user, website) => Object.assign({}, user, { adultVideo: website }))
);
const renameUser = gaurdedFn(
userType,
curry((user, firstName, lastName) => Object.assign({}, user, {firstName, lastName}))
);
const User = function(user) {
enforceType(userType, user);
this.firstName = user.firstName;
this.lastName = user.lastName;
this.sex = user.sex;
this.age = user.age;
this.rename = renameUser(this);
this.watchVideo = watchVideo(this);
this.watchAdultVideo = watchAdultVideo(this);
}
const assert = (isTrue, msg) => { if (!isTrue) throw new Error(msg)};
const isNamedFizzbuzz = enforceType(where({ firstName: equals('fizz'), lastName: equals('buzz') }))
const isNamedFooBar = enforceType(where({ firstName: equals('foo'), lastName: equals('bar') }))
let adult = new User({firstName: 'foo', lastName: 'bar', age: 20, sex: 'F'});
assert(isNamedFooBar(adult), 'Should get default names');
adult = adult.rename("fizz", "buzz")
assert(isNamedFizzbuzz(adult), 'Should rename properly');
console.log(adult.watchVideo("youtube"));
console.log(adult.watchAdultVideo("pornhub"));
const child = new User({firstName: 'foo', lastName: 'bar', age: 11, sex: 'F'});
console.log(child.rename("fizz", "buzz"));
console.log(child.watchVideo("youtube"));
console.log([
{firstName: 'billy', lastName: 'bob', age: 11, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 17, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 18, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 19, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 99, sex: 'F'}
].map(watchVideo).map(fn => fn('youtube.com')));
console.log([
{firstName: 'billy', lastName: 'bob', age: 11, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 17, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 18, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 19, sex: 'F'},
{firstName: 'foo', lastName: 'bar', age: 99, sex: 'F'}
].map(watchAdultVideo).map(fn => fn && fn('pornhub.com')));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment