Last active
January 9, 2019 23:08
-
-
Save Restuta/da489a3f77d9f8dc6be1e0aaac2db15a to your computer and use it in GitHub Desktop.
Effect Functor / Reader Monad
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
// effect functor | |
const Effect = f => ({ | |
map: g => Effect(x => g(f(x))), | |
run: x => f(x), | |
join: x => f(x), | |
chain: f => | |
Effect(f) | |
.map(g) | |
.join(), | |
ap: eff => { | |
// If someone calls ap, we assume eff has a function inside it (rather than a value). | |
// We'll use map to go inside off, and access that function (we'll call it 'g') | |
// Once we've got g, we apply the value inside off f() to it | |
return eff.map(g => g(f())); | |
}, | |
}); | |
Effect.of = val => Effect(() => val); | |
// zero :: () -> Number | |
function fZero(x) { | |
console.log('Starting with nothing ' + x); | |
// Definitely not launching a nuclear strike here. | |
// But this function is still impure. | |
return x; | |
} | |
// const zero = Effect(fZero); | |
const zero = Effect.of(0); | |
const increment = x => x + 1; | |
const one = zero | |
.map(increment) | |
// .chain(x => 2) | |
.map(increment) | |
.map(x => x * x); | |
one.run(3); //? | |
const Reader = f => ({ | |
join: x => f(x), //join | |
run: x => f(x), //join | |
chain: g => Reader(x => g(f(x)).join(x)), //chain | |
// chain: g => Reader(f).map(g).join(), | |
// chain: f => | |
// Reader(f) | |
// .map(g) | |
// .join(), | |
map: g => Reader(x => g(f(x))), | |
ap: eff => eff.map(g => g(f())), | |
ask: () => Reader(x => x) | |
}); | |
Reader.of = val => Reader(() => val); | |
Reader.ask = () => Reader(x => x) | |
// const reader1 = Reader.of(1) | |
// .chain(x => Reader.of(1)) | |
// .map(x => x + 1); | |
// | |
// reader1.run(2); //? | |
const db = { | |
update(x) { | |
console.log('updating ' + x); | |
}, | |
}; | |
const log = x => console.log(x); | |
const updateTask = taskData => { | |
console.log('task run'); | |
return Reader.ask() | |
.map(db => db.update(taskData)) | |
.ask() | |
.map(log => log('logging A')); | |
}; | |
console.info('running...') | |
updateTask('task data A').run(db, log); //? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment