Skip to content

Instantly share code, notes, and snippets.

@StanAngeloff
Created January 23, 2017 15:02
Show Gist options
  • Save StanAngeloff/67f343f8ce8b4a426e243a39fb3fff85 to your computer and use it in GitHub Desktop.
Save StanAngeloff/67f343f8ce8b4a426e243a39fb3fff85 to your computer and use it in GitHub Desktop.
const curry = (fx) => {
const arity = fx.length;
return function f1(...args) {
return args.length >= arity ? fx.apply(null, args) : function f2(...args2) {
return f1.apply(null, args.concat(args2));
};
};
};
const compose = (...fs) => {
return function(...args) {
for (let i = fs.length - 1; i >= 0; i--) {
const f = fs[i];
const a = f.length ? args.slice(0, f.length) : args;
args = args.slice(f.length || 1);
args.unshift(f.apply(this, a));
}
return args[0];
};
};
const map = curry((f, xs) => xs.map(f));
const join = (m) => m.join();
const chain = curry((f, m) => m.map(f).join());
const head = curry((xs) => xs[0]);
const concat = curry((a, b) => a.concat(b));
class IO {
constructor(f) {
this.unsafePerformIO = f;
}
static of(x) {
return new IO(() => x);
}
map(f) {
return new IO(compose(f, this.unsafePerformIO));
}
join() {
return new IO(() => this.unsafePerformIO().unsafePerformIO());
}
chain(f) {
return this.map(f).join();
}
}
class Maybe {
constructor(x) {
this.__value = x;
}
static of(x) {
return new Maybe(x);
}
isNothing() {
return this.__value === null || this.__value === undefined;
}
map(f) {
return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value));
}
join() {
return this.isNothing() ? Maybe.of(null) : this.__value;
}
chain(f) {
return this.map(f).join();
}
}
//
const fs = require('fs');
const readFile = (filename) => new IO(() => fs.readFileSync(filename, 'utf-8'));
const print = (x) => new IO(() => console.log(x) || x);
const cat = compose(map(print), readFile);
const firstChr = compose(map(map(head)), cat);
// console.info(
// firstChr('./package.json').join().join()
// );
// console.info(
// IO.of(new IO(function() {
// return console.log('impure') || 'impure';
// })).join().join()
// );
//
const safeProp = curry((x, obj) => Maybe.of(obj[x]));
const safeHead = safeProp(0);
const firstStreetAddress = compose(
chain(safeProp('street')),
chain(safeHead),
safeProp('addresses')
);
console.info(
firstStreetAddress({ addresses: [{ street: { name: 'Bulgaria Blvd.' } }] })
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment