Comparing version 12.0.0-beta.2 to 12.0.0-beta.3
90
index.js
@@ -30,3 +30,12 @@ (function (global, factory) { | ||
var nil = {head: null}; | ||
function List(head, tail){ | ||
this.head = head; | ||
this.tail = tail; | ||
} | ||
List.prototype.toJSON = function(){ | ||
return toArray(this); | ||
}; | ||
var nil = new List(null, null); | ||
nil.tail = nil; | ||
@@ -41,3 +50,3 @@ | ||
function cons(head, tail){ | ||
return {head: head, tail: tail}; | ||
return new List(head, tail); | ||
} | ||
@@ -67,2 +76,13 @@ | ||
// toArray :: List a -> Array a | ||
// -- O(n) list to Array | ||
function toArray(xs){ | ||
var tail = xs, arr = []; | ||
while(!isNil(tail)){ | ||
arr.push(tail.head); | ||
tail = tail.tail; | ||
} | ||
return arr; | ||
} | ||
/* istanbul ignore next: non v8 compatibility */ | ||
@@ -323,2 +343,14 @@ var captureStackTrace = Error.captureStackTrace || captureStackTraceFallback; | ||
function getArgs(it){ | ||
var args = new Array(it.arity); | ||
for(var i = 1; i <= it.arity; i++){ | ||
args[i - 1] = it['$' + String(i)]; | ||
} | ||
return args; | ||
} | ||
function showArg$1(arg){ | ||
return ' (' + show(arg) + ')'; | ||
} | ||
var any = {pred: alwaysTrue, error: invalidArgumentOf('be anything')}; | ||
@@ -404,10 +436,10 @@ var func = {pred: isFunction, error: invalidArgumentOf('be a Function')}; | ||
Future.prototype.toString = function(){ | ||
var str = this.name; | ||
for(var i = 1; i <= this.arity; i++){ | ||
str += ' (' + show(this['$' + String(i)]) + ')'; | ||
} | ||
return str; | ||
Future.prototype.toString = function Future$toString(){ | ||
return this.name + getArgs(this).map(showArg$1).join(''); | ||
}; | ||
Future.prototype.toJSON = function Future$toJSON(){ | ||
return {$: $$type, kind: 'interpreter', type: this.name, args: getArgs(this)}; | ||
}; | ||
function createInterpreter(arity, name, interpret){ | ||
@@ -527,3 +559,4 @@ var Interpreter = function(context, $1, $2, $3){ | ||
var Transformer = createInterpreter(2, '', function Transformer$interpret(rec, rej, res){ | ||
var Transformer = | ||
createInterpreter(2, 'transform', function Transformer$interpret(rec, rej, res){ | ||
@@ -542,3 +575,3 @@ //These are the cold, and hot, transformation stacks. The cold actions are those that | ||
//Takes an transformation from the top of the hot stack and returns it. | ||
//Takes a transformation from the top of the hot stack and returns it. | ||
function nextHot(){ | ||
@@ -550,3 +583,3 @@ var x = hot.head; | ||
//Takes an transformation from the top of the cold stack and returns it. | ||
//Takes a transformation from the top of the cold stack and returns it. | ||
function nextCold(){ | ||
@@ -675,14 +708,5 @@ var x = cold.head; | ||
Transformer.prototype.toString = function Transformer$toString(){ | ||
var i, str = this.$1.toString(), str2, tail = this.$2; | ||
while(!isNil(tail)){ | ||
str2 = tail.head.name; | ||
for(i = 1; i <= tail.head.arity; i++){ | ||
str2 += ' (' + show(tail.head['$' + String(i)]) + ')'; | ||
} | ||
str = str2 + ' (' + str + ')'; | ||
tail = tail.tail; | ||
} | ||
return str; | ||
return toArray(reverse(this.$2)).reduce(function(str, action){ | ||
return action.name + getArgs(action).map(showArg$1).join('') + ' (' + str + ')'; | ||
}, this.$1.toString()); | ||
}; | ||
@@ -700,2 +724,6 @@ | ||
function BaseTransformation$toJSON(){ | ||
return {$: $$type, kind: 'transformation', type: this.name, args: getArgs(this)}; | ||
} | ||
var BaseTransformation = { | ||
@@ -708,3 +736,4 @@ rejected: BaseTransformation$rejected, | ||
arity: 0, | ||
name: 'transform' | ||
name: 'transform', | ||
toJSON: BaseTransformation$toJSON | ||
}; | ||
@@ -1349,4 +1378,4 @@ | ||
} | ||
cancel = Hook$cancelDisposal; | ||
disposal._interpret(Hook$rec, Hook$disposalRejected, Hook$done); | ||
cancel = Hook$cancelDisposal; | ||
} | ||
@@ -1534,5 +1563,8 @@ | ||
var max = Math.min(this.$1, length), cancels = new Array(length), out = new Array(length); | ||
var cursor = 0, running = 0, blocked = false; | ||
var cursor = 0, running = 0, blocked = false, cont = noop; | ||
function Parallel$cancel(){ | ||
rec = noop; | ||
rej = noop; | ||
res = noop; | ||
cursor = length; | ||
@@ -1545,9 +1577,11 @@ for(var n = 0; n < length; n++) cancels[n] && cancels[n](); | ||
cancels[idx] = futures[idx]._interpret(function Parallel$rec(e){ | ||
cont = rec; | ||
cancels[idx] = noop; | ||
Parallel$cancel(); | ||
rec(wrapException(e, _this)); | ||
cont(wrapException(e, _this)); | ||
}, function Parallel$rej(reason){ | ||
cont = rej; | ||
cancels[idx] = noop; | ||
Parallel$cancel(); | ||
rej(reason); | ||
cont(reason); | ||
}, function Parallel$res(value){ | ||
@@ -1554,0 +1588,0 @@ cancels[idx] = noop; |
{ | ||
"name": "fluture", | ||
"version": "12.0.0-beta.2", | ||
"version": "12.0.0-beta.3", | ||
"description": "FantasyLand compliant (monadic) alternative to Promises", | ||
@@ -70,3 +70,3 @@ "main": "index", | ||
"es-check": "^5.0.0", | ||
"eslint": "^5.5.0", | ||
"eslint": "^6.2.1", | ||
"eslint-config-warp": "^3.0.0", | ||
@@ -77,10 +77,10 @@ "esm": "^3.0.81", | ||
"mocha": "^6.1.2", | ||
"nyc": "^14.1.0", | ||
"nyc": "^14.1.1", | ||
"ramda": "^0.26.1", | ||
"remark-cli": "^6.0.0", | ||
"remark-validate-links": "^8.0.0", | ||
"rimraf": "^2.6.2", | ||
"remark-cli": "^7.0.0", | ||
"remark-validate-links": "^9.0.1", | ||
"rimraf": "^3.0.0", | ||
"rollup": "^1.0.0", | ||
"rollup-plugin-commonjs": "^10.0.0", | ||
"rollup-plugin-node-resolve": "^5.0.0", | ||
"rollup-plugin-commonjs": "^10.0.2", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"sanctuary-benchmark": "^1.0.0", | ||
@@ -90,4 +90,4 @@ "sanctuary-either": "^1.1.0", | ||
"typescript": "^3.0.3", | ||
"xyz": "github:davidchambers/xyz#bee6fbe" | ||
"xyz": "github:davidchambers/xyz#340d089" | ||
} | ||
} |
119
README.md
@@ -102,3 +102,3 @@ # [![Fluture](logo.png)](#butterfly) | ||
Fluture is hosted in full with all of its dependencies at | ||
https://cdn.jsdelivr.net/gh/fluture-js/Fluture@12.0.0-beta.2/dist/bundle.js | ||
https://cdn.jsdelivr.net/gh/fluture-js/Fluture@12.0.0-beta.3/dist/bundle.js | ||
@@ -140,2 +140,3 @@ This script will add `Fluture` to the global scope. | ||
- [Debugging with Fluture](#debugging) | ||
- [Casting Futures to String](#casting-futures-to-string) | ||
- [Usage with Sanctuary](#sanctuary) | ||
@@ -238,5 +239,21 @@ - [Using multiple versions of Fluture](#casting-futures) | ||
The various function signatures are provided in a small language referred to as | ||
Hindley-Milner notation. Read about [Hindley-Milner in JavaScript][Guide:HM] | ||
here. | ||
Hindley-Milner notation. | ||
In summary, the syntax is as follows: `InputType -> OutputType`. Now, | ||
because functions in Fluture are [curried][Guide:currying], the "output" of a | ||
function is often *another function*. In Hindley-Milner that's simply written | ||
as `InputputType -> InputToSecondFunction -> OutputType` and so forth. | ||
By convention, types starting with an upper-case letter are | ||
[concrete types](#types). When they start with a lower-case letter they're | ||
*type variables*. You can think of these type variables as generic types. | ||
So `a -> b` denotes a function from generic type `a` to generic type `b`. | ||
Finally, through so-called [*constraints*](#type-classes), type variables can | ||
be forced to conform to an "interface" (or *Type Class* in functional jargon). | ||
For example, `MyInterface a => a -> b`, denotes a function from generic type | ||
`a` to generic type `b`, *where `a` must implement `MyInterface`*. | ||
You can read in depth about [Hindley-Milner in JavaScript][Guide:HM] here. | ||
#### Types | ||
@@ -384,5 +401,6 @@ | ||
- `future`: The instance of [`Future`](#future) that was being | ||
[consumed](#consuming-futures) when the exception happened. Often printing it | ||
as a String can yield useful information. You can also try to consume it in | ||
isolation to better identify what's going wrong. | ||
[consumed](#consuming-futures) when the exception happened. Often | ||
[printing it as a String](#casting-futures-to-string) can yield useful | ||
information. You can also try to consume it in isolation to better identify | ||
what's going wrong. | ||
@@ -397,2 +415,66 @@ Finally, as mentioned, Fluture has a [debug mode](#debugmode) wherein | ||
### Casting Futures to String | ||
There are multiple ways to print a Future to String. Let's take a simple | ||
computation as an example: | ||
```js | ||
const add = a => b => a + b; | ||
const eventualAnswer = ap (resolve (22)) (map (add) (resolve (20))); | ||
``` | ||
1. Casting it to String directly by calling `String(eventualAnswer)` or | ||
`eventualAnswer.toString()` will yield an approximation of the code that | ||
was used to create the Future. In this case: | ||
```js | ||
"ap (resolve (22)) (map (a => b => a + b) (resolve (20)))" | ||
``` | ||
2. Casting it to String using `JSON.stringify(eventualAnswer, null, 2)` will | ||
yield a kind of abstract syntax tree. | ||
```json | ||
{ | ||
"$": "fluture/Future@5", | ||
"kind": "interpreter", | ||
"type": "transform", | ||
"args": [ | ||
{ | ||
"$": "fluture/Future@5", | ||
"kind": "interpreter", | ||
"type": "resolve", | ||
"args": [ | ||
20 | ||
] | ||
}, | ||
[ | ||
{ | ||
"$": "fluture/Future@5", | ||
"kind": "transformation", | ||
"type": "ap", | ||
"args": [ | ||
{ | ||
"$": "fluture/Future@5", | ||
"kind": "interpreter", | ||
"type": "resolve", | ||
"args": [ | ||
22 | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"$": "fluture/Future@5", | ||
"kind": "transformation", | ||
"type": "map", | ||
"args": [ | ||
null | ||
] | ||
} | ||
] | ||
] | ||
} | ||
``` | ||
### Sanctuary | ||
@@ -711,3 +793,3 @@ | ||
For comparison, the equivalent with Promises is: | ||
For comparison, an approximation with Promises is: | ||
@@ -743,9 +825,14 @@ ```js | ||
For comparison, the equivalent with Promises is: | ||
For comparison, an approximation with Promises is: | ||
```js | ||
> Promise.resolve (41) | ||
. .then (x => x + 1, x => x + '!') | ||
. .then (x => x + 1, x => Promise.reject (x + '!')) | ||
. .then (log ('resolution'), log ('rejection')) | ||
[resolution]: 42 | ||
> Promise.reject ('It broke!') | ||
. .then (x => x + 1, x => Promise.reject (x + '!')) | ||
. .then (log ('resolution'), log ('rejection')) | ||
[rejection]: "It broke!!" | ||
``` | ||
@@ -776,3 +863,3 @@ | ||
For comparison, the equivalent with Promises is: | ||
For comparison, an approximation with Promises is: | ||
@@ -822,3 +909,3 @@ ```js | ||
For comparison, the equivalent with Promises is: | ||
For comparison, an approximation with Promises is: | ||
@@ -848,3 +935,3 @@ ```js | ||
For comparison, the equivalent with Promises is: | ||
For comparison, an approximation with Promises is: | ||
@@ -883,3 +970,3 @@ ```js | ||
For comparison, the equivalent with Promises is: | ||
For comparison, an approximation with Promises is: | ||
@@ -891,2 +978,7 @@ ```js | ||
[resolution]: Right ("hello") | ||
> Promise.reject ('It broke!') | ||
. .then (S.Right, S.Left) | ||
. .then (log ('resolution'), log ('rejection')) | ||
[resolution]: Left ("It broke!") | ||
``` | ||
@@ -1522,2 +1614,3 @@ | ||
[Guide:constraints]: https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html#constraints | ||
[Guide:currying]: https://drboolean.gitbooks.io/mostly-adequate-guide-old/content/ch4.html | ||
@@ -1524,0 +1617,0 @@ [1]: https://en.wikipedia.org/wiki/Continuation-passing_style |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
172767
3221
1611