https://github.com/thimoteus/purescript-promises
An alternative effect monad for PureScript.
https://github.com/thimoteus/purescript-promises
javascript promise purescript
Last synced: 9 days ago
JSON representation
An alternative effect monad for PureScript.
- Host: GitHub
- URL: https://github.com/thimoteus/purescript-promises
- Owner: Thimoteus
- License: mit
- Created: 2017-08-25T06:23:42.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-05-08T18:09:22.000Z (almost 6 years ago)
- Last Synced: 2025-03-12T09:43:40.532Z (about 1 month ago)
- Topics: javascript, promise, purescript
- Language: PureScript
- Size: 62.5 KB
- Stars: 23
- Watchers: 3
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# purescript-promises
[](https://travis-ci.org/Thimoteus/purescript-promises)An alternative effect monad for PureScript.
Use this for easy interop with existing promise-based JavaScript libraries.
## Usage
With monadic `do` notation, or with promise-chaining notation. The following are
equivalent:```purescript
myApply :: forall a b. Promise (a -> b) -> Promise a -> Promise b
myApply pab pa = do
ab <- pab
a <- pa
pure (ab a)myApplyChained :: forall a b. Promise (a -> b) -> Promise a -> Promise b
myApplyChained pab pa = pab # then' \ ab -> pa # then' \ a -> resolve (ab a)
```in fact, if you squint a little, `myApplyChained` looks like the following JavaScript:
```javascript
var myApplyChained = function (pab, pa) {
pab.then(function (ab) {
pa.then(function (a) {
return Promise.resolve(ab(a));
});
});
}
```Also see the `tests` folder.
### eagerness
While promises are [eager](https://medium.com/@avaq/broken-promises-2ae92780f33),
this library provides the `Deferred` typeclass to ensure promises don't prematurely
run their side-effects until safely consumed with `runPromise`, or the nonstandard
`done`.In fact, not only are promises eager, but they're eager about being eager. They *really*
want to run:### delay example
```purescript
promDelay :: Deferred => Promise Unit
promDelay = do
p1
p2
p3
where
p1 = do
Console.log "one"
Promise.delay (Milliseconds 1000.0) unit
Console.log "two"
p2 = do
Promise.delay (Milliseconds 1000.0) unit
Console.log "three"
p3 = do
Promise.delay (Milliseconds 1000.0) unit
Console.log "four"
```this will output `one`, wait one second, then `four` `three` `two`.
In order to obtain the desired behavior of waiting one second between
*each* log, it's necessary to add type annotations to `p1`, `p2` and
`p3`:```purescript
p1 :: Deferred => Promise Unit
p1 = do ...
```### parallel `(<*>)`
```purescript
promApply :: Deferred => Promise Unit
promApply = p1 *> p2 *> p3
where
p1 :: Deferred => Promise Unit
p1 = do
Console.log "<*> is"
Promise.delay (Milliseconds 1000.0) unit
Console.log "done"
p2 :: Deferred => Promise Unit
p2 = do
Promise.delay (Milliseconds 3000.0) unit
Console.log "parallel"
p3 :: Deferred => Promise Unit
p3 = do
Promise.delay (Milliseconds 2000.0) unit
Console.log "in"
```Note that difference (between this example and the last) that we're using `(*>)`
instead of implicit `(>>=)`s. And even though we added the `Deferred` constraint,
it will still take 3 seconds to run total -- not 6, as it would be using do notation.### FFI example
```javascript
exports.myPromise = new Promise(function (resolve, reject) {
resolve(5);
});
``````purescript
foreign import myPromise :: Promise IntdoSomething :: Deferred => Promise Unit
doSomething = do
p <- myPromise
Console.logShow pmain :: Effect Unit
main
= runPromise
(const (log "success callback"))
(const (error "error callback"))
doSomething
```## Installation
`bower install --save purescript-promises`
## See also
* [purescript-aff-promise](https://github.com/nwolverson/purescript-aff-promise)
* [purescript-aff](https://github.com/slamdata/purescript-aff)