Created
January 23, 2017 15:02
-
-
Save StanAngeloff/67f343f8ce8b4a426e243a39fb3fff85 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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