Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename and improve fromPromise #98

Merged
merged 5 commits into from
May 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ For front-end applications and node <v4, please use `require('fluture/es5')`.
* [rejectAfter](#rejectafter)
* [try](#try)
* [encase](#encase)
* [fromPromise](#frompromise)
* [encaseP](#encasep)
* [node](#node)
* [chainRec](#chainrec)
1. [Transforming Futures](#transforming-futures)
Expand Down Expand Up @@ -254,29 +254,30 @@ safeJsonParse(data).fork(console.error, console.log)
Furthermore; `encase2` and `encase3` are binary and ternary versions of
`encase`, applying two or three arguments to the given function respectively.

#### fromPromise
##### `.fromPromise :: (a -> Promise e r) -> a -> Future e r`
##### `.fromPromise2 :: (a, b -> Promise e r) -> a -> b -> Future e r`
##### `.fromPromise3 :: (a, b, c -> Promise e r) -> a -> b -> c -> Future e r`
#### encaseP
##### `.tryP` :: (a -> Promise e r) -> Future e r
##### `.encaseP :: (a -> Promise e r) -> a -> Future e r`
##### `.encaseP2 :: (a, b -> Promise e r) -> a -> b -> Future e r`
##### `.encaseP3 :: (a, b, c -> Promise e r) -> a -> b -> c -> Future e r`

Allows Promise-returning functions to be turned into Future-returning functions.

Takes a function which returns a Promise, and a value, and returns a Future
which calls the function to produce the Promise, and resolves with the Promise
resolution value, or rejects with the Promise rejection reason.
Takes a function which returns a Promise, and a value, and returns a Future.
When forked, the Future calls the function with the value to produce the Promise,
and resolves with its resolution value, or rejects with its rejection reason.

```js
const fetchf = Future.fromPromise(fetch);
const fetchf = Future.encaseP(fetch);

fetchf('https://api.github.com/users/Avaq')
.chain(res => Future.fromPromise(_ => res.json(), 0))
.chain(res => Future.tryP(_ => res.json()))
.map(user => user.name)
.fork(console.error, console.log);
//> "Aldwin Vlasblom"
```

Furthermore; `fromPromise2` and `fromPromise3` are binary and ternary versions
of `fromPromise`, applying two or three arguments to the given function respectively.
Furthermore; `encaseP2` and `encaseP3` are binary and ternary versions
of `encaseP`, applying two or three arguments to the given function respectively.

#### node
##### `.node :: (((a, b) -> ()) -> ()) -> Future a b`
Expand Down
2 changes: 1 addition & 1 deletion index.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export {after} from './src/after';
export {cache} from './src/cache';
export {chainRec} from './src/chain-rec';
export {encase, encase2, encase3, attempt, attempt as try} from './src/encase';
export {fromPromise, fromPromise2, fromPromise3} from './src/from-promise';
export {encaseP, encaseP2, encaseP3, tryP} from './src/encase-p';
export {go, go as do} from './src/go';
export {hook} from './src/hook';
export {node} from './src/node';
Expand Down
93 changes: 93 additions & 0 deletions src/encase-p.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {Core} from './core';
import {noop, show, showf, partial1, partial2, partial3} from './internal/fn';
import {isThenable, isFunction} from './internal/is';
import {invalidArgument, typeError} from './internal/throw';

function escape(f){
return function imprisoned(x){
setTimeout(function escaped(){ f(x) }, 0);
};
}

function check$promise(p, f, a, b, c){
return isThenable(p) ? p : typeError(
'Future.encaseP expects the function its given to return a Promise/Thenable'
+ `\n Actual: ${show(p)}\n From calling: ${showf(f)}`
+ `\n With a: ${show(a)}`
+ (arguments.length > 3 ? `\n With b: ${show(b)}` : '')
+ (arguments.length > 4 ? `\n With c: ${show(c)}` : '')
);
}

function EncaseP$0$fork(rej, res){
const {_fn} = this;
check$promise(_fn(), _fn).then(escape(res), escape(rej));
return noop;
}

function EncaseP$1$fork(rej, res){
const {_fn, _a} = this;
check$promise(_fn(_a), _fn, _a).then(escape(res), escape(rej));
return noop;
}

function EncaseP$2$fork(rej, res){
const {_fn, _a, _b} = this;
check$promise(_fn(_a, _b), _fn, _a, _b).then(escape(res), escape(rej));
return noop;
}

function EncaseP$3$fork(rej, res){
const {_fn, _a, _b, _c} = this;
check$promise(_fn(_a, _b, _c), _fn, _a, _b, _c).then(escape(res), escape(rej));
return noop;
}

const forks = [EncaseP$0$fork, EncaseP$1$fork, EncaseP$2$fork, EncaseP$3$fork];

function EncaseP(fn, a, b, c){
this._length = arguments.length - 1;
this._fn = fn;
this._a = a;
this._b = b;
this._c = c;
this._fork = forks[this._length];
}

EncaseP.prototype = Object.create(Core);

EncaseP.prototype.toString = function EncaseP$toString(){
const args = [this._a, this._b, this._c].slice(0, this._length).map(show).join(', ');
const name = `encaseP${this._length > 1 ? this._length : ''}`;
return `Future.${name}(${show(this._fn)}, ${args})`;
};

export function tryP(f){
if(!isFunction(f)) invalidArgument('Future.tryP', 0, 'be a function', f);
return new EncaseP(f);
}

export function encaseP(f, x){
if(!isFunction(f)) invalidArgument('Future.encaseP', 0, 'be a function', f);
if(arguments.length === 1) return partial1(encaseP, f);
return new EncaseP(f, x);
}

export function encaseP2(f, x, y){
if(!isFunction(f)) invalidArgument('Future.encaseP2', 0, 'be a function', f);
switch(arguments.length){
case 1: return partial1(encaseP2, f);
case 2: return partial2(encaseP2, f, x);
default: return new EncaseP(f, x, y);
}
}

export function encaseP3(f, x, y, z){
if(!isFunction(f)) invalidArgument('Future.encaseP3', 0, 'be a function', f);
switch(arguments.length){
case 1: return partial1(encaseP3, f);
case 2: return partial2(encaseP3, f, x);
case 3: return partial3(encaseP3, f, x, y);
default: return new EncaseP(f, x, y, z);
}
}
76 changes: 0 additions & 76 deletions src/from-promise.js

This file was deleted.

9 changes: 5 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {after} from './after';
import {cache} from './cache';
import {chainRec} from './chain-rec';
import {encase, encase2, encase3, attempt} from './encase';
import {fromPromise, fromPromise2, fromPromise3} from './from-promise';
import {encaseP, encaseP2, encaseP3, tryP} from './encase-p';
import {go} from './go';
import {hook} from './hook';
import {node} from './node';
Expand All @@ -36,9 +36,10 @@ export default Object.assign(Future, dispatchers, {
isNever,
after,
cache,
fromPromise,
fromPromise2,
fromPromise3,
encaseP,
encaseP2,
encaseP3,
tryP,
hook,
node,
Par,
Expand Down
Loading