Skip to content

Instantly share code, notes, and snippets.

@homam
Created July 8, 2016 20:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save homam/3479cdb83484b404c44bb554fc5ee64d to your computer and use it in GitHub Desktop.
Save homam/3479cdb83484b404c44bb554fc5ee64d to your computer and use it in GitHub Desktop.
Callback-monad-then-only
class Callback {
constructor(f) {
// this.run = f
this.run = callback => {
try {
f(callback)
} catch (ex) {
callback(ex, null)
}
}
// this.map = ...
// this.bind = ...
// 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 8, 2016

Full version (including bind and map): https://gist.github.com/homam/5d583f0fcd04a0a0ccbdf2ba0eb861c3#file-callback-monad-js

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

const operation = Callback.pure(5)
.then(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