async-ls v0.0.3
async-ls
This library provides powerful higher-order functions and other utilities for working with asynchronous functions with callbacks or ES6 promises.
Callback utility functions are in
{callbacks} = require \async-lsand promise based functions are in
{promises} = require \async-lsThere's also a monad library accessible by:
{monads} = require \async-lsCallback and promise functions are similar in their input arguments and their result. Callback functions return a callback function with the signature of (error, result) -> void and promise functions return a Promise object.
To get the individual functions use LiveScript pattern matching syntax:
{
promises: {
LazyPromise, parallel-map, parallel-limited-filter
},
monads: {
filterM, liftM
}
} = require \async-lsTo build:
make buildBuild for browsers (using Browserify):
make async-browser.jsBuild for browsers (callbacks library only):
make callbacks-browser.js Build for browsers (promises library only):
make promises-browser.jsTo test:
./test.shMonads
{monads} = require \async-lsmonadize
Monads work best in statically typed languages. To make monadic functions
work in LiveScript, we need to pass the type of the monad to many of the monadic operations.
monadize encapsulates the monad's type: return aka pure, fmap and bind functions.
monadize ::
(a -> m a) -> # pure
((a -> b) -> m a -> m b) -> # fmap
(m a -> (a -> m b) -> m b) -> # bind
MonadkcompM
Left-to-right Kleisli composition of monads.
kcompM :: (Monad m) => (a -> m b) -> (b -> m c) -> (a -> m c)joinM
Remove one level of monadic structure, projecting its bound argument into the outer level.
(Monad m) => m m x -> m xfilterM
Filter the list by applying the predicate function to each of its element one-by-one in serial order.
filterM :: (Monad x) => (x -> m Boolean) -> [x] -> m [x]foldM
The foldM function is analogous to foldl, except that its result is
encapsulated in a monad.
foldM :: (Monad a) => (a -> b -> m a) -> a -> [b] -> m asequenceM
Evaluate each action in the sequence from left to right, and collect the results.
sequenceM :: (Monad x) => [m x] -> m [x]mapM
It is equivalent to sequenceM . (map f).
(Monad m) => (x -> m x) -> [x] -> m [x]liftM
Promote a function to a monad.
liftM :: (Monad m) => (a -> r) -> m a -> m rliftM2
Promote a function to a monad, scanning the monadic arguments from left to right.
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m rap
monad.pureM f `ap` x1 `ap` ... `ap` is equivalent to (liftMn monad) f x1 x2 ... xn
ap :: (Monad m) => m (a -> b) -> m a -> m bSome Monad Instances:
list-monad :: Monad # []
either-monad :: Monad # [error, right]
writer-monad :: Monad # [value, monoid]Promises
{promises} = require \async-lsLazy Promise
LazyPromise only starts getting evaluated after then is called.
LazyPromise : PromiseCompositions
promise-monad :: MonadreturnP
Inject a value into a promise.
returnP :: x -> Promise xfmapP
Map a normal function over a promise.
fmapP :: (x -> y) -> Promise x -> Promise yffmapP
fmapP with its arguments flipped.
ffmapP :: Promise x -> (x -> y) -> Promise ybindP
Sequentially compose two promises, passing the value produced by the first as an argument to the second.
bindP :: Promise x -> (x -> Promise y) -> Promise yfbindP
bindP with its arguments flipped.
fbindP :: (x -> Promise y) -> Promise x -> Promise yfilterP
Filter the list by applying the promise predicate function to each of its element one-by-one in serial order.
filterP :: (x -> Promise Boolean) -> [x] -> Promise [x]foldP
The foldP function is analogous to foldl, except that its result is
encapsulated in a promise.
foldP :: (a -> b -> Promise a) -> a -> [b] -> Promise asequenceP
Run its input (an array of Promise s) in parallel
(without waiting for the previous promise to fulfill),
and return the results encapsulated in a promise.
The returned promise immidiately gets rejected, if any of the promises in the input list fail.
sequenceP :: [Promise x] -> Promise [x]Lists
parallel-map
parallel-map :: (a -> Promise b) -> [a] -> Promise [b]serial-map
serial-map :: (a -> Promise b) -> [a] -> Promise [b]parallel-limited-map
parallel-limited-map :: Int -> (x -> Promise y) -> [x] -> Promise [y]parallel-filter
parallel-filter :: (x -> m Boolean) -> [x] -> m [x]serial-filter
Synonym for filterP
serial-filter :: (x -> Promise Boolean) -> [x] -> Promise [x]parallel-limited-filter
parallel-limited-filter :: Int -> (x -> Promise Boolean) -> [x] -> Promise xparallel-any
Run the boolean predicate (that is encapsulated in a promise) on the list in parallel.
The returned promise fulfills as soon as a matching item is found with true,
otherwise false if no match was found.
parallel-any :: (x -> Promise Boolean) -> [x] -> Promise Booleanserial-any
serial-any :: (x -> m Boolean) -> [x] -> m Booleanparallel-limited-any
parallel-limited-any :: Int -> (x -> Promise Boolean) -> [x] -> Promise Booleanparallel-all
parallel-all :: (x -> Promise Boolean) -> [x] -> Promise Booleanserial-all
serial-all :: (x -> Promise Boolean) -> [x] -> Promise Booleanparallel-limited-all
parallel-limited-all :: Int -> (x -> Promise Boolean) -> [x] -> Promise Booleanparallel-find
Run the boolean predicate (that is encapsulated in a promise) on the list in parallel.
The returned promisefulfills as soon as a matching item is found with the
matching value, otherwise with null if no match was found.
parallel-find :: (x -> Promise Boolean) -> [x] -> m serial-find
serial-find :: (x -> Promise Boolean) -> [x] -> m xparallel-limited-find
parallel-limited-find :: Int -> (x -> Promise Boolean) -> [x] -> Promise xparallel-sequence
Synonym for sequenceP
parallel-sequence :: [Promise x] -> Promise [x]serial-sequence
The serial version of sequenceP.
To run the list one by one in a serial order, its items
must be instances of LazyPromise type.
This function runs the list in parallel, if it is a list
of normal Promise s.
serial-sequence :: [LazyPromise x] -> LazyPromise [x]parallel-limited-sequence
parallel-limited-sequence :: Int -> [LazyPromise x] -> LazyPromise [x]parallel-apply-each
parallel-apply-each :: x -> [x -> Promise y] -> Promise [y]serial-apply-each
serial-apply-each :: x -> [x -> Promise y] -> Promise [y]parallel-limited-apply-each
parallel-limited-apply-each :: x -> [x -> Promise y] -> Promise [y]parallel-sort-by
Sort the list using the given function for making the comparison between the items.
parallel-sort-by :: (a -> Promise b) -> [a] -> Promise [a]parallel-sort-with
parallel-sort-with takes a binary function which compares two items and returns either
a positive number, 0, or a negative number, and sorts the inputted list
using that function.
parallel-sort-with :: (a -> a -> Promise i) -> [a] -> Promise [a]waterfall
waterfall :: x -> (x -> Promise x) -> Promise xtransform-promise-either
Bind a promise monad to an either monad. The result is a promise monad. Since we can think of promise as a superset of either in the way it handles errors.
transform-promise-either :: Promise x -> (x -> Either y) -> Promise yftransform-promise-either
transform-promise-either with its arguments flipped.
ftransform-promise-either :: (x -> Either y) -> Promise x -> Promise ytransform-either-promise
Bind an either monad to a promise monad.
transform-either-promise :: Either x -> (x -> Promise y) -> Promise yftransform-either-promise
transform-either-promise with its arguments flipped.
ftransform-either-promise :: (x -> Promise y) -> Either x -> Promise yto-callback
Convert the promise object to a callback with the signature of (error, result) -> void
Promise x -> CB xfrom-value-callback
Make a promise object from a callback with the signature of (result) -> void, like fs.exist
Cb x -> Promise xfrom-error-value-callback
Make a promise object from a callback with the signature of (error, result) -> void, like fs.stat
CB x -> Promise xfrom-named-callbacks
Make a promise object from obj.
String -> String -> obj -> Promise xCallbacks
These functions are analogous to their promise-based counterparts that are documented above.
But instead of a Promise their last argument is a callback. You can think of curried version of these functions as functions that return a function that takes callback.
{callbacks} = require \prelude-lsConvention
This would be our definition of asynchronous functions:
If function
freturns functiongandgtakes acallbackas its only argument; thenfis an asynchronous function.
Our callbacks will always receive two parameters: (error, result).
Here CB a stands for a callback function with signature: (err, a) -> void
You can get the result of an asynchronous function (with a callback of type of CB a) by:
(err, a) <- fComposition of Asynchronous Actions
returnA
Inject a value into an asynchronous action.
returnA :: x -> CB xfmapA
Map a normal function over an asynchronous action.
fmapA :: (x -> y) -> CB x -> CB yffmapA
fmapA with its arguments flipped
ffmapA :: CB x -> (x -> y) -> CB ybindA
Sequentially compose two asynchronous actions, passing the value produced by the first as an argument to the second.
bindA :: CB x -> (x -> CB y) -> CB yfbindA
bindA with its arguments flipped
fbindA :: (x -> CB y) -> CB x -> CB ykcompA
Similar to Left-to-right Kleisli composition, kcompA composes
two asynchronous actions passing the value produced
by the first as an argument to the second. The result is a new
asynchronous function that takes the argument of the first function.
kcompA :: (x -> CB y) -> (y -> CB z) -> (x -> CB z)foldA
The foldA function is analogous to foldl, except that its result is
encapsulated in an asynchronous callback.
foldA :: (a -> b -> m a) -> a -> [b] -> m asequenceA
Evaluate each action in the sequence from left to right, and collect the results.
sequenceA :: [CB x] -> CB [x]filterA
Filter the list by applying the asynchronous predicate function.
filterA :: (x -> CB Boolean) -> [x] -> CB [x]Either
returnE
Inject a value into an either action.
returnE :: x -> Either xfmapE
fmapE :: (x -> y) -> Either x -> Either yfmapE
ffmapE :: Either x -> (x -> y) -> Either ybindE
bindE :: Either x -> (x -> Either y) -> Either ybindE
bindE :: (x -> Either y) -> Either x -> Either ykcompE
Left to right Kleisli composition
kcompE :: (x -> Either y) -> (y -> Either z) -> (x -> Either z)foldE
foldE :: (a -> b -> Either a) -> a -> [b] -> Either asequenceE
sequenceE :: [Either x] -> Either [x]transformAE
transformAE :: CB x -> (x -> Either y) -> CB yftransformAE
ftransformAE :: (x -> Either y) -> CB x -> CB ytransformEA
transformEA :: Either x -> (x -> CB y) -> CB yftransformEA
ftransformEA :: (x -> CB y) -> Either x -> CB yLists
Map
parallel-map
parallel-map :: (a -> CB b) -> [a] -> CB [b]serial-map
Serial Asynchronous Map
serial-map :: (a -> CB b) -> [a] -> CB [b]parallel-map-limited
Similar to parallel-map, only no more than
limit iterators will be simultaneously running at any time.
parallel-map-limited :: Int -> (x -> CB y) -> [x] -> CB [y]Filter
parallel-filter
parallel-filter :: (x -> CB Boolean) -> [x] -> CB [x]serial-filter
serial-filter :: (x -> CB Boolean) -> [x] -> CB [x]parallel-limited-filter
parallel-limited-filter :: Int -> (x -> CB Boolean) -> [x] -> CB xAny, All, Find
parallel-any
parallel-any :: (x -> CB Boolean) -> [x] -> CB Booleanserial-any
serial-any :: (x -> CB Boolean) -> x -> CB Boolean
parallel-limited-any
parallel-limited-any :: Int -> (x -> CB Boolean) -> [x] -> CB Booleanparallel-all
parallel-all :: (x -> CB Boolean) -> [x] -> CB Booleanserial-all
serial-all :: (x -> CB Boolean) -> [x] -> CB Booleanparallel-limited-all
parallel-limited-all :: Int -> (x -> CB Boolean) -> [x] -> CB Booleanparallel-find
paralel-find :: (x -> CB Boolean) -> [x] -> CB xserial-find
serial-find :: (x -> CB Boolean) -> [x] -> CB xSort
parallel-sort-by
Sorts a list using the inputted function for making the comparison between the items.
parallel-sort-by :: (a -> CB b) -> [a] -> CB [a]parallel-sort-with
Takes a binary function which compares two items and returns either a positive number, 0, or a negative number, and sorts the inputted list using that function.
parallel-sort-with :: (a -> a -> CB i) -> [a] -> CB [a]Control Flow
serial-sequence
serial-sequence :: [CB x] -> CB [x]parallel-sequence
Run its sole input (a tasks array of functions) in parallel, without waiting until the previous function has completed. If any of the functions pass an error to its callback, the main callback is immediately called with the value of the error. Once the tasks have completed, the results are passed to the final callback as an array.
parallel-sequence :: [CB x] -> CB [x]parallel-limited-sequence
parallel-limited-sequence :: Int -> [CB x] -> CB [x]parallel-apply-each
parallel-apply-each :: x -> [x -> CB y] -> CB [y]serial-apply-each
serial-apply-each :: x -> [x -> CB y] -> CB [y]parallel-limited-apply-each
parallel-limited-apply-each :: x -> [x -> CB y] -> CB [y]waterfall
waterfall :: x -> (x -> CB x) -> CB xserial-fold
serial-fold :: (a -> b -> m a) -> a -> [b] -> m a