Last active
August 29, 2015 14:01
-
-
Save micmarsh/e9dcccf81ffdede88aff to your computer and use it in GitHub Desktop.
Haskell Do Notation for JavaScript Promises
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
COMPILED_COFFEE = ' < -' | |
PLAIN_JS = '<-' | |
thenify = (lines) -> | |
[line, rest...] = lines | |
if rest.length is 0 | |
line | |
else if line.search(PLAIN_JS) > 0 or line.search(COMPILED_COFFEE) > 0 | |
[value, promise] = line.split if line.search(PLAIN_JS) > 0 then PLAIN_JS else COMPILED_COFFEE | |
noSemiColon = promise.slice(0, -1) | |
"return #{noSemiColon}.then(function(#{value}){"+ | |
thenify(rest) + | |
"});" | |
else | |
line + '\n' + thenify rest | |
doPromise = (fn) -> | |
lines = fn.toString().split '\n' | |
withArgs = lines[0] | |
body = lines.slice(1, -1).map (x) -> x.trim() | |
newFn = thenify(body) | |
with: (args...)-> | |
eval("(#{withArgs}#{newFn}})")(args...) | |
# EXAMPLE | |
# doPromise (get, savetoDatabase)-> | |
# data <- get 'some stuff' | |
# ids <- saveToDatabase data | |
# {data, ids} | |
# .with get, savetoDatabase | |
# | |
# compiles to: | |
# | |
# doPromise(function(get, savetoDatabase) { | |
# data < -get('some stuff'); | |
# ids < -saveToDatabase(data); | |
# return { | |
# data: data, | |
# ids: ids | |
# }; | |
# })["with"](get, savetoDatabase); | |
# | |
# which gets transformed into this: | |
# | |
# function (get, saveToDatabase) { | |
# return get('some stuff').then(function (data) { | |
# return saveToDatabase(data).then(function (ids) { | |
# return { | |
# data: data, | |
# ids: ids | |
# }; | |
# }); | |
# })["with"](get, savetoDatabase); | |
# | |
# yay monads! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment