Skip to content

Instantly share code, notes, and snippets.

@homam
Last active March 2, 2017 19:39
Show Gist options
  • Save homam/5d583f0fcd04a0a0ccbdf2ba0eb861c3 to your computer and use it in GitHub Desktop.
Save homam/5d583f0fcd04a0a0ccbdf2ba0eb861c3 to your computer and use it in GitHub Desktop.
class Callback {
constructor(f) {
// this.run = f
this.run = callback => {
try {
f(callback)
} catch (ex) {
callback(ex, null)
}
}
// this :: Callback x
// (x -> y) -> Callback y
this.map = g => new Callback(callback => {
this.run((error, ...result) => {
if(!!error) {
callback(error, null)
} else {
callback(null, g(...result))
}
})
})
// this :: Callback x
// (x -> Callback y) -> Callback y
this.bind = g => new Callback(callback => {
this.run((error, ...result) => {
if(!!error) {
callback(error, null)
} else {
g(...result).run(callback)
}
})
})
// this :: Callback x
// x -> (y || Callback y) -> Callback y
this.then = g => new Callback(callback => {
this.run((error, ...result) => {
if(!!error) {
callback(error, null)
} else {
try {
const y = g(...result)
if (y instanceof Callback) {
y.run(callback)
} else {
callback(null, y)
}
} catch(ex) {
callback(ex, null)
}
}
})
})
this.bindTo = g => this.bind(Callback.from(g))
}
}
// x -> Callback x
Callback.pure = x => new Callback(cb => cb(null, x))
Callback.resolve = Callback.pure
// Callback.from casts f into a Callback instance, where
// f is a function that takes x and a callback function
Callback.from = f => (...x) => new Callback(cb => f(...x, cb))
@homam
Copy link
Author

homam commented Jul 2, 2016

Usage: https://jsbin.com/jazadi/edit?js,console

const operation = Callback.pure(5)
.bind(x => new Callback(cb => {
  console.log(`binding ${x} to x + 1`)
  setTimeout(() => cb(null, x + 1), 100)
}))

operation.run((error, result) => console.log(error || result))

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