Last active
December 29, 2020 12:21
-
-
Save Sylvenas/2a06088257344bc1596ed03407194f49 to your computer and use it in GitHub Desktop.
Functional programming Task async in parallel
This file contains 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
// Task(functor,applicative,monad) | |
const Task = fork => ({ | |
map: f => Task((reject, resolve) => | |
fork(reject, a => resolve(f(a)))), | |
ap: fn => | |
Task((reject, resolve) => fork(reject, a => | |
fn.map(a).fork(reject, resolve) | |
)), | |
chain: f => | |
Task((reject, resolve) => fork(reject, a => | |
f(a).fork(reject, resolve))), | |
fork, | |
[Symbol.for('nodejs.util.inspect.custom')]: () => 'Task(?)' | |
}) | |
// lift | |
Task.of = a => Task((_, resolve) => resolve(a)) | |
// --------------------------async------------ | |
// async get user name | |
const fetchName = Task((_, resolve) => { | |
setTimeout(() => { | |
resolve('Melo') | |
}, 2000) | |
}); | |
// async get user age | |
const fetchAge = Task((_, resolve) => { | |
setTimeout(() => { | |
resolve(24) | |
}, 2000) | |
}); | |
// pure app | |
const app = Task | |
.of(name => age => ({ name, age })) | |
.ap(fetchName) | |
.ap(fetchAge) | |
// effect | |
app.fork(() => { | |
console.log('something went wrong') | |
}, x => { | |
console.log('x', x) // 4 seconds later log {name:'Melo', age:24} | |
}) |
I will actually need a Mandarin translation for my course on Github at some point. However, for the time being everything is still in flux, chapters are revised. Translating it makes only sense when things get more stable.
Similar to Promise.all
. But the ap
function only needs to receive one Task.
const Task = fork => ({
ap: fn => Task((reject, resolve) => {
let func, rejected
const firstState = fork(x => {
rejected = true;
return reject(x)
}, x => func = x)
const senondState = fn.fork(x => {
rejected = true;
return reject(x)
}, x => {
if (rejected) return
return resolve(func(x))
})
return [firstState, senondState]
})
})
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great post! Thanks.
Do you have a plan to put all posts on github? I can do the translation (chinese) work.