Skip to content

Instantly share code, notes, and snippets.

@spion
Forked from robotlolita/0-specification.md
Last active June 26, 2016 20:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save spion/b433a665ca51d6c38e9f to your computer and use it in GitHub Desktop.
Save spion/b433a665ca51d6c38e9f to your computer and use it in GitHub Desktop.
Future and ReaderT with auto-lifting and example
class Future {
constructor(computation) {
this.fork = computation
this.__future__ = true;
}
static is(val) {
return (val != null && val.__future__ === true)
}
static of(value) {
if (Future.is(value)) return value;
return new Future((resolve, reject) => resolve(value))
}
static err(e) {
if (Future.is(e)) return e;
return new Future((resolve, reject) => reject(e))
}
chain(f) {
return new Future((resolve, reject) =>
this.fork(value => Future.of(f(value)).fork(resolve, reject), reject))
}
orElse(f) {
return new Future((resolve, reject) =>
this.fork(resolve, error => Future.of(f(error)).fork(resolve, reject)))
}
}
var ReaderT = (M) => class ReaderT {
constructor(computation) {
this.computation = computation
this.__reader__ = true;
}
static is(val) {
return (val != null && val.__reader__ === true)
}
runWith(data) {
return this.computation(data)
}
chain(f) {
return new ReaderT(data => this.computation(data).chain(a => ReaderT.of(f(a)).runWith(data)));
}
static of(val) {
if (ReaderT.is(val)) return val;
return new ReaderT(data => M.of(val))
}
static ask() {
return new ReaderT(data => M.of(data))
}
}
var fs = require('fs')
var readFile = path => new Future((resolve, reject) => fs.readFile(path, 'utf8', (err, res) => err ? reject(err) : resolve(res)))
var SuperFuture = ReaderT(Future)
var doStuffx = () => getUserId().chain(id => readFile(id + '.txt'))
var getUserId = () => SuperFuture.ask().chain(user => user.id)
// From the route handler, we only pass the user id once.
// It automatically propagates through the SuperFutures
app.get('/some/url', function(req, res) {
doStuffx().runWith({id: req.user.id}).fork(data => res.end(data), err => console.error(err))
})
@JoyKrishnaMondal
Copy link

wondering if could mix this with most.js streams - and how

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment