(ES6 required)
(please disregard the culture references in the examples)
The contents of this package are organized into submodules:
F: general functions and constants
This library is to provide support for pure functional programming by providing convenience functions in curried form.
Here is an example:
// summing up an array
function sum_array(array) {
var ans = 0;
for (var i = 0; i < array.length; i++) {
ans += array[i];
}
return ans;
}
// summing up a array of arrays
function sum_arrays(array) {
var ans = 0;
for (var i = 0; i < array.length; i++) {
ans += sum_array(array[i]);
}
return ans;
}
// summing up a array of arrays of arrays
function sum_arrays2(array) {
var ans = 0;
for (var i = 0; i < array.length; i++) {
ans += sum_arrays(array[i]);
}
return ans;
}
The above code, functionally:
const green_curry = require ('green_curry') (['globalize', 'short F.c']})
// summing up a array
const sum_array = A.fold (F ['+']) (0)
// summing up a array of arrays
const sum_arrays = F.c (A.map (sum_array) >> sum_array)
// summing up a array of arrays of arrays
const sum_arrays2 = F.c (A.map (sum_arrays) >> sum_array)
An understanding of the typed lambda calculus, currying, JavaScript type system, closures, and mutability are recommended for effective use of this library. All functions are free of self-references, allowing their safe use as first-class functions. All functions are pure, except globalize, F.c, and F.p.
Initializer options are compatible with each other
Pulls the included submodules into global scope to obviate the need for fully-qualifying each resource
All examples on this page will assume this has already been called
(note: works both in-server and in-browser)
var green_curry = require ('green_curry') (['globalize'])
F.log ('Hint: 3?') // prints 'Hint: 3?'
Removes the need for the first call to F.c
(note: this will break compatibility of nested F.c and F.p, and as such it is recommended to avoid this for any non-trivial project)
var green_curry = require ('green_curry') (['short F.c'])
var f = green_curry.F.c ((x => `Hint: ${x}?`) >> green_curry.F.log)
f ('3') // prints 'Hint: 3?'
(note: regard the operators as prefix notation)
The identity function
Generates a constant function
Does nothing
Executes the given function
Throw x
An alias for console.log.bind (console)
Aliasing and calling console.log by itself without binding will throw an exception
Same as curried JSON.stringify and then console.log
Deep comparison of x and y
Compares the equality of x and y coerced to x's type
Compares the equality of x and y
Compares the inequality of x and y coerced to x's type
Compares the inequality of x and y
Returns if x is greater than y
Returns if x is greater than or equal to y
Returns if x is lesser than y
Returns if x is lesser than or equal to y
Negates x
2's complements x
Adds x by y
Subtracts x by y
Multiplies x by y
Divides x by y
Modulo divides x by y
Bitwise ors x by y
Logical ors x by y
(note: the arguments are evaluated eagerly so this does not short-circuit)
Bitwise ands x by y
Logical ands x by y
(note: the arguments are evaluated eagerly so this does not short-circuit)
Bitwise xors x by y
Sign-propagating right shifts x by y
Zero-fill right shifts x by y
Left shifts x by y
Returns x if it is not null and y otherwise
(note: the arguments are evaluated eagerly so this does not short-circuit)
Returns y if x and z otherwise
(note: the arguments are evaluated eagerly so this does not short-circuit)
Calls f with x and returns the result
Calls f with x and returns the result
Function composes f and g
Reverse function composes f and g
Returns a predicate that is the negation of f
Returns a predicate that is a union of f and g
Returns a predicate that is an intersection of f and g
Calls the first function and returns the result
If an exception is thrown, passes it to the second function and returns the result
Essentially try/catch as an expression
F.try (() => {
F.log ('Hint: 3?')
throw new Error ()
})
.catch (err => {
F.log (true)
}) // prints 'Hint: 3?' then true
Swaps the order of the next two arguments of f
Calls f after waiting x millisecons
Calls f with x and returns x
(note: for side-effecting when you want to retain the reference)
Reverse function composes the functions in fs
Reverse function composes fs with a temporary DSL
(note: this is safe for nested usage in other instances of F.c and F.p)
(note: works by overriding Function.valueOf)
var f = F.c () (
F.tap (F.log)
>> F['='] ('Hint: 3?')
>> F.tap (F.log)
)
f ('Hint: 3?') // true // prints 'Hint: 3?' then 'true'
Reverse function composes fs with a temporary DSL and calls that with x and returns the result
(note: this is safe for nested usage in other instances of F.c and F.p)
(note: works by overriding Function.valueOf)
F.p ('Hint: 3?') (
F.tap (F.log)
>> F['='] ('Hint: 3?')
>> F.tap (F.log)
) == true // prints 'Hint: 3?' then 'true'
Returns a memoized version f
(note: the memoization has O(n) lookup)
Invokes f x times
Returns a version of f that does nothing and returns undefined until the xth time when it reverts to normal
Returns a version of f that operates normally until the xth time when it starts doing nothing and returns undefined
Returns the value of the first matching case
If no cases are matched and it is terminated with default, then the default case is executed
If no cases are matched and it is terminated with end, then an exception is thrown
F.match (3)
.case (1) (x => x + 5)
.case (2) (x => x + 4)
.case (3) (x => x)
.default (x => x + 3) == 3
Same as F.match, but takes predicate functions as cases
Promise-based utility functions are contained in the F.P submodule
Same as F.try, but supports promised functions
Only the expression as a whole returns a promise
await F.P.try (async () => {
F.log ('Hint: 3?')
throw new Error ()
})
.catch (async err => {
F.log (true)
}) // prints 'Hint: 3?' then true
(note: arrays are assumed to be dense, meaning all data is contiguous)
(note: all respective orders are preserved, except in obvious cases)
Returns a shallow copy of xs
Prepends x to l
Throws an exception if xs is empty and returns the first element of xs otherwise
Throws an exception if xs is empty and returns all elements of xs except the first otherwise
Returns the length of l
Returns whether the length of xs is 0
Returns the xth element in xs if it exists and returns undefined otherwise
Returns the numbers between x and y, double inclusive, if x is less than or equal to y and an empty array otherwise
Returns y repeated x times
Returns an array of x elements generated by f passed each index
Returns xs with the elements in reverse order
Calls f on each element in l
Same as A.iter, except additionally passes the index as well
Calls f on the accumulator, initialized at a, and each element of xs and returns the result
Throws an exception is xs is empty and is the same as A.fold with the accumulator initialized to the first element in xs otherwise
Same as A.fold, but additionally returns all of the partial sums
Returns xs with each element transformed by f
Same as A.map, but additionally passes the index as well
Returns the first element in xs for which f returns true and throws an error if one does not exist
Returns the first element in xs for which f returns true and returns undefined if one does not exist
Returns the index of the first element in xs for which f returns true and throws an error if one does not exist
Returns the index of the first element in xs for which f returns true and returns undefined if one does not exist
Returns the result of f for the first element in xs for which f does not return undefined and throws an error if one does not exist
Returns the result of f for the first element in xs for which f does not return undefined and throws an error if one does not exist
Returns xs without the elements for which f returns false
Returns if f is true for all elements in l, vacuously true
Returns if f is true for any element in l, vacuously false
Returns if any element in xs is equal to x
Returns xs sorted by f determined by normal comparator standards
Returns xs into two arrays, the first containing all elements for which f is true and the second containing everything else
Returns xs with duplicates removed
Returns xs with duplicates removed according to the mapping through f
(note: this is substantially faster than A.uniq)
Returns the arrays of the first element of each element of xs and the second element of each element of l
(note: this function does not enforce density)
Returns an array of xss flattened by one level
Returns l1 prepended to l2
Returns if l1 and l2 have equal lengths
Returns if l1 and l2 have unequal lengths
Throws exception F.e if l1 and l2 have unequal lengths and is the same as A.iter, but with corresponding elements of each array passed in otherwise
Same as A.iter2, except additionally passing the index
Throws exception F.e if l1 and l2 have unequal lengths and is the same as A.fold, but with corresponding elements of each array passed in otherwise
Throws exception F.e if l1 and l2 have unequal lengths and is the same as A.map, but with corresponding elements of each array passed in otherwise
Throws exception F.e if l1 and l2 have unequal lengths and is the same as A.mapi, but with corresponding elements of each array passed in otherwise
Throws exception F.e if l1 and l2 have unequal lengths and is the same as A.for_all, but with corresponding elements of each array passed in otherwise
Throws exception F.e if l1 and l2 have unequal lengths and is the same as A.exists, but with corresponding elements of each array passed in otherwise
Throws exception F.e if l1 and l2 have unequal lengths and returns the corresponding elements of l1 and l2 combined
Deep comparison of x and y
Promise-based array functions are contained in the A.P submodule, with A.P.s serial and A.P.p parallel submodules
Serial functions will operate in order and will reject on the first error or resolve on success
Parallel functions will initiate all operations at the same time and will resolve when all operations complete or reject on the first error before that
Not all functions are available in both modes
Returns an array of x elements generated by f passed each index
Calls f on each element in l
Same as A.iter, except additionally passes the index as well
Calls f on the accumulator, initialized at a, and each element of xs and returns the result
Throws an exception is xs is empty and is the same as A.fold with the accumulator initialized to the first element in xs otherwise
Same as A.fold, but additionally returns all of the partial sums
Returns xs with each element transformed by f
Same as A.map, but additionally passes the index as well
Returns the first element in xs for which f returns true and throws an error if one does not exist
Returns the first element in xs for which f returns true and returns undefined if one does not exist
Returns the result of f for the first element in xs for which f does not return undefined and throws an error if one does not exist
Returns the result of f for the first element in xs for which f does not return undefined and throws an error if one does not exist
Returns xs without the elements for which f returns false
Returns if f is true for all elements in l, vacuously true
Returns if f is true for any element in l, vacuously false
Returns if d is empty
Returns the element in d with key k
Returns d with key k set to value v
Returns the dictionary with pairs of each element with the first element as the key and the second element as the value
Returns the keys of d
Returns the values of d
Returns the key, value pairs of d
Binds the self-references for functions inside d to d and returns d
(note: this one of the gaps I mentioned in the opening; in languages that automatically resolve this problem, it's not an issue)
Freezes d and returns d
Same as D.bind then D.freeze
Same as A.iter on the values of d, except with keys instead of indices
Same as D.iter, except additionally passing the key
Same as A.fold on the values of d
Same as D.fold, except additionally passing the key
Same as A.map on the values of d
Same as D.map, except additionally passing the key
Same as A.find on the values of d
Same as D.find, except additionally passing the key
Same as A.filter on the values of d
Same as D.filter, except additionally passed the key
Same as A.for_all on the values of d
Same as A.exists on the values of d
Same as A.contains on the values of d
Same as A.contains on the keys of d
Returns the number of key, value pairs in d
D.partition : (f: 'a -> bool) -> (d: 'b, 'a dictionary) -> (('b, 'a) dictionary * ('b, 'a) dictionary)
Same as A.partition on the values of d
Returns d1 overlaid by d2
Returns d with only the pairs with keys in xs
Returns d without the pairs with keys in xs
Deep comparison of d1 and d2
Returns the length of x
Returns the xth character in y
Returns the substring from x to y in z with some slice logic
Returns the first index at which x appears in y
Returns if x appears at least once in y
Follows normal comparator rules for strings for comparing x to y
Returns the match and capture groups of r in x if x matches r and null otherwise
Returns y with matches of r replaced by x
Same as S.index, except with the last occurence
Returns the first index that x matches r
Returns a array of the substrings of x split by r
Returns x with all characters lowercase
Returns x with all characters uppercase
Returns x without surrounding whitespace
Returns if x and y are equal
Returns the string of all strings in xs with x in between each element