UNPKG

1.23 kBJavaScriptView Raw
1/* @flow weak */
2"use strict";
3
4/**
5 #### isPromise p : bool
6
7 Optimistic duck-type check for promises.
8 Returns `true` if p is an object with `.then` function property.
9*/
10function isPromise(p) {
11 /* eslint-disable no-new-object */
12 return new Object(p) === p && typeof p.then === "function";
13 /* eslint-enable non-new-object */
14}
15
16/**
17 #### map (Functor f) => (p : f a) (g : a -> b) : f b
18
19 This is functor map, known as `map` or `fmap`.
20 Essentially `f(p)`. If `p` is promise, returns new promise.
21 Using `map` makes code look very much [CPS-style](http://en.wikipedia.org/wiki/Continuation-passing_style).
22*/
23function map(p, g) {
24 if (isPromise(p)) {
25 return p.then(g);
26 } else {
27 return g(p);
28 }
29}
30
31/**
32 #### bind (Functor f) => (k : a -> f b) (xs : a) (h : b -> f c) -> f c
33
34 This is almost monadic bind.
35*/
36function bind(f, xs, h) {
37 var r;
38 var exc;
39 try {
40 r = f.apply(undefined, xs);
41 } catch (e) {
42 r = false;
43 exc = e;
44 }
45
46 if (isPromise(r)) {
47 return r.then(
48 h,
49 function (e) {
50 // exc is always unset here
51 return h(false, e);
52 }
53 );
54 } else {
55 return h(r, exc);
56 }
57}
58
59module.exports = {
60 isPromise: isPromise,
61 map: map,
62 bind: bind,
63};