Package Exports
- rambda
- rambda/modules/prop
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (rambda) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Rambda
Faster alternative to Ramda in just 10kB - Documentation
Rambda's advantages
- Tree-shaking
Currenly Rambda is more tree-shakable than Ramda as you can see in this tree-shaking example.
- Speed
Rambda is generally more performant than Ramda as the benchmarks can prove that.
You can clone this repo and run yarn run benchmark all to see for yourself.
- Minor helpers
For example with Rambda you can call R.path('a.b', {a: {b: 1}}) instead of R.path(['a','b'], {a: {b: 1}})
In Rambda you can use both types of expression.
This is not a major change, but some developers would prefer to use 'a.b.c' over ['a', 'b', 'c'].
Same logic is applied to R.omit method.
R.pick is similar, but the separator is , not .
Initial argumentation
I admire Ramda, as it is great library in what it does. My main problem was its size. Even custom builds didn't deliver satisfactory results. Also I already had Ramda habits and I didn't want to switch to Lodash.
Then I realized that my best solution was to publish a library that recreates the functionality of some Ramda methods with less code.
Rambda partially shadows Ramda's API, so you need to check in Rambda's documentation, if the methods you need are available.
Generally speaking, if you have never used methods such as R.transduce, Rambda API should be enough for your needs.
Example use
const R = require('rambda')
const result = R.compose(
R.filter( R.equals( 2 ) ),
R.map( R.add( 1 ) )
)({ a: 1, b: 2, c: 3 })
console.log(result) // => '{a: 2}'Install
Use yarn add rambda for
WebpackandNode.jsusageFor UMD usage either use
./dist/rambda.umd.jsor the CDN link at
https://cdnjs.cloudflare.com/ajax/libs/rambda/1.0.0/webVersion.jsDifferences between Rambda and Ramda
Rambda's type detect async functions and unresolved
Promises. The returned values are'Async'and'Promise'.Rambda's equals doesn't protect against circular structures as Ramda.equals does.
Rambda's path, pick and omit accepts both string and array as condition argument('x.y.z' == ['x','y','z']).
Rambda's flip works only for functions expecting two arguments.
Rambda's partialCurry and includes are not part of Ramda API.
Rambda's startsWith/endsWith work only with strings, instead with array and strings.
If you need more Ramda methods in Rambda, you may either submit a
PRor check the extended version of Rambda - Rambdax
API
add
add(a: Number, b: Number): Number
R.add(2, 3) // => 5addIndex
addIndex(fn: Function): Function
const mapWithIndex = R.addIndex(R.map)
mapWithIndex(
(val, index) => `${val} - ${index}`,
['A', 'B', 'C']
) // => ['A - 0', 'B - 1', 'C - 2']adjust
adjust(replaceFn: Function, i:Number, arr:Array): Array
It replaces i index in arr with the result of replaceFn(arr[i]).
R.adjust(a => a + 1, 0, [0, 100]) // => [1, 100]all
all(fn: Function, arr: Array): Boolean
It returns true if all members of array arr returns true, when applied as argument to function fn.
const arr = [ 0, 1, 2, 3, 4 ]
const fn = x => x > -1
R.all(fn, arr) // => true
allPass
allPass(rules: Array
, input: any): Boolean
It returns true if all functions of rules return true, when input is their argument.
const input = {
a : 1,
b : 2,
}
const rules = [
x => x.a === 1,
x => x.b === 2,
]
R.allPass(rules, obj) // => true
always
always(x: any): Function
It returns function that always returns x.
const fn = R.always(7)
fn()// => 7
fn()// => 7
any
any(condition: Function, arr: Array): Boolean
It returns true if at least one member of arr returns true,
when passed to the condition function.
R.any(a => a * a > 8)([1, 2, 3]) // => true
R.any(a => a * a > 10)([1, 2, 3]) // => falseappend
append(valueToAppend: any, arr: Array): Array
R.append('foo', ['bar', 'baz']) // => ['foo', 'bar', 'baz']both
both(x: Function, y: Function, input: any): Boolean
It returns true if both function x and function y return true, when input is their argument.
const fn = R.both(
a => a > 10,
a => a < 20
)
fn(15) //=> true
fn(30) //=> false
compose
compose(fn1: Function, ... , fnN: Function): any
It performs right-to-left function composition.
const result = R.compose(
R.map(x => x * 2)
R.filter(x => x > 2),
)([1, 2, 3, 4])
console.log(result) // => [6, 8]
complement
complement(fn: Function): Function
It returns complemented function that accept input as argument.
The return value of complemented is the negative boolean value of fn(input).
R.complement(R.always(0)) // => true
R.complement(R.always(true)) // => false
concat
concat(x: array|string, y: array|string): array|string
It returns a new string or array, which is the result of merging x and y.
R.concat([1, 2])([3, 4]) // => [1, 2, 3, 4]
R.concat('foo', 'bar') // => 'foobar'contains
contains(valueToFind: any, arr: Array): Boolean
It returns true if valueToFind is part of arr.
R.contains(2, [1, 2]) // => true
R.contains(3, [1, 2]) // => falsecurry
curry(fn: Function): Function
It returns curried version of fn.
const addFourNumbers = (a, b, c, d) => a + b + c + d
const curriedAddFourNumbers = R.curry(addFourNumbers)
const f = curriedAddFourNumbers(1, 2)
const g = f(3)
g(4) // => 10dec
dec(x: number): number
It decrements a number.
R.dec(2) // => 1defaultTo
defaultTo(defaultValue: T, inputArgument: any): T
It returns defaultValue, if inputArgument is undefined, null or NaN.
It returns inputArgument in any other case.
R.defaultTo('foo', undefined) // => 'foo'
R.defaultTo('foo', 'bar') // => 'bar'
R.defaultTo('foo', 1) // => 1divide
R.divide(71, 100) // => 0.71drop
drop(howManyToDrop: Number, arrOrStr: Array|String): Array|String
It returns arrOrStr with howManyToDrop items dropped from the left.
R.drop(1, ['foo', 'bar', 'baz']) // => ['bar', 'baz']
R.drop(1, 'foo') // => 'oo'dropLast
dropLast(howManyToDrop: Number, arrOrStr: Array|String): Array|String
It returns arrOrStr with howManyToDrop items dropped from the right.
R.dropLast(1, ['foo', 'bar', 'baz']) // => ['foo', 'bar']
R.dropLast(1, 'foo') // => 'fo'endsWith
endsWith(x: String, str: String): Boolean
R.endsWith(
'bar',
'foo-bar'
) // => true
R.endsWith(
'foo',
"foo-bar"
) // => falseeither
const fn = R.either(
a => a > 10,
a => a % 2 === 0
)
fn(15) //=> true
fn(6) //=> true
fn(7) //=> falseequals
equals(a: any, b: any): Boolean
It returns equality match between a and b.
It doesn't handle cyclical data structures.
R.equals(1, 1) // => true
R.equals({}, {}) // => false
R.equals([1, 2, 3], [1, 2, 3]) // => trueF
R.F() // => false
filter
filter(filterFn: Function, arr: Array): Array
Filters arr throw boolean returning filterFn
const filterFn = a => a % 2 === 0
R.filter(filterFn, [1, 2, 3, 4]) // => [2, 4]find
find(findFn: Function, arr: Array
): T|undefined
It returns undefined or the first element of arr satisfying findFn.
const findFn = a => R.type(a.foo) === "Number"
const arr = [{foo: "bar"}, {foo: 1}]
R.find(findFn, arr) // => {foo: 1}findIndex
findIndex(findFn: Function, arr: Array): Number
It returns -1 or the index of the first element of arr satisfying findFn.
const findFn = a => R.type(a.foo) === "Number"
const arr = [{foo: "bar"}, {foo: 1}]
R.find(findFn, arr) // => 1flatten
flatten(arr: Array): Array
R.flatten([ 1, [ 2, [ 3 ] ] ])
// => [ 1, 2, 3 ]flip
flip(fn: Function): Function
It returns function which calls fn with exchanged first and second argument.
const subtractFlip = R.flip(R.subtract)
R.subtractFlip(1,7)
// => 6forEach
forEach(fn: Function, arr: Array): Array
It applies function fn over all members of array arr and returns arr.
const sideEffect = {}
const result = R.forEach(
x => sideEffect[`foo${x}`] = x
)([1, 2])
console.log(sideEffect) //=> {foo1 : 1, foo2 : 2}
console.log(result) //=> [1, 2]Note, that unlike Ramda's forEach, Rambda's one doesn't dispatch to forEach method of arr.
has
has(prop: String, obj: Object): Boolean
- It returns
trueifobjhas propertyprop.
R.has("a", {a: 1}) // => true
R.has("b", {a: 1}) // => falsehead
head(arrOrStr: Array|String): any
It returns the first element of arrOrStr.
R.head([1, 2, 3]) // => 1
R.head('foo') // => 'f'identity
identity(x: T): T
It just passes back the supplied arguments.
R.identity(7) // => 7ifElse
ifElse(condition: Function|boolean, ifFn: Function, elseFn: Function): Function
It returns function, which expect input as argument and returns finalResult.
When this function is called, a value answer is generated as a result of condition(input).
If answer is true, then finalResult is equal to ifFn(input).
If answer is false, then finalResult is equal to elseFn(input).
const fn = R.ifElse(
x => x > 10,
x => x*2,
x => x*10
)
fn(8) // => 80
fn(11) // => 22inc
inc(x: number): number
It increments a number.
R.inc(1) // => 2includes
includes(x: any, arrOrStr: Array|String): Boolean
R.includes(1, [1, 2]) // => true
R.includes('oo', 'foo') // => true
R.includes('z', 'foo') // => false!! Note that this method is not part of Ramda API.
indexOf
indexOf(valueToFind: any, arr: Array): Number
It returns -1 or the index of the first element of arr equal of valueToFind.
R.indexOf(1, [1, 2]) // => 0init
init(arrOrStr: Array|String): Array|String
- It returns all but the last element of
arrOrStr.
R.init([1, 2, 3]) // => [1, 2]
R.init('foo') // => 'fo'join
join(separator: String, arr: Array): String
R.join('-', [1, 2, 3]) // => '1-2-3'is
isNil(xPrototype: any, x: any): boolean
It returns true is x is instance of xPrototype.
R.is(String, 'foo') // => true
R.is(Array, 1) // => falseisNil
isNil(x: any): Boolean
It returns true is x is either null or undefined.
R.isNil(null) // => true
R.isNil(1) // => falselast
last(arrOrStr: Array|String): any
- It returns the last element of
arrOrStr.
R.last(['foo', 'bar', 'baz']) // => 'baz'
R.last('foo') // => 'o'lastIndexOf
lastIndexOf(x: any, arr: Array): Number
It returns the last index of x in array arr.
R.equals is used to determine equality between x and members of arr.
Value -1 is returned if no x is found in arr.
R.lastIndexOf(1, [1, 2, 3, 1, 2]) // => 3
R.lastIndexOf(10, [1, 2, 3, 1, 2]) // => -1length
length(arrOrStr: Array|String): Number
R.length([1, 2, 3]) // => 3map
map(mapFn: Function, arr: Array): Array
It returns the result of looping through arr with mapFn.
const mapFn = x => x * 2;
R.map(mapFn, [1, 2, 3]) // => [2, 4, 6]match
match(regExpression: Regex, str: String): Array
R.match(/([a-z]a)/g, 'bananas') // => ['ba', 'na', 'na']merge
merge(a: Object, b: Object)
It returns result of Object.assign({}, a, b).
R.merge({ 'foo': 0, 'bar': 1 }, { 'foo': 7 })
// => { 'foo': 7, 'bar': 1 }modulo
modulo(a: Number, b: Number): Number
It returns the remainder of operation a/b.
R.module(14,3) // => 2multiply
multiply(a: Number, b: Number): Number
It returns the result of operation a*b.
R.module(14,3) // => 2not
not(x: any): Boolean
It returns inverted boolean version of input x.
R.not(true); //=> false
R.not(false); //=> true
R.not(0); //=> true
R.not(1); //=> falseomit
omit(propsToOmit: Array
, obj: Object): Object
It returns a partial copy of an obj with omitting propsToOmit
R.omit(['a', 'd'], {a: 1, b: 2, c: 3}) // => {b: 2, c: 3}path
path(pathToSearch: Array
|String, obj: Object): any
If pathToSearch is 'a.b' then it will return 1 if obj is {a:{b:1}}.
It will return undefined, if such path is not found.
R.path('a.b', {a: {b: 1}}) // => 1
R.path(['a', 'b'], {a: {b: 2}}) // => 2
R.path(['a', 'c'], {a: {b: 2}}) // => undefinedpathOr
pathOr(defaultValue: any, pathToSearch: Array
|String, obj: Object): any
pathFound is the result of calling R.path(pathToSearch, obj).
If pathFound is undefined, null or NaN, then defaultValue will be returned.
pathFound is returned in any other case.
R.pathOr(1, 'a.b', {a: {b: 2}}) // => 2
R.pathOr(1, ['a', 'b'], {a: {b: 2}}) // => 2
R.pathOr(1, ['a', 'c'], {a: {b: 2}}) // => 1partialCurry
partialCurry(fn: Function|Async, a: Object, b: Object): Function|Promise
When called with function fn and first set of input a, it will return a function.
This function will wait to be called with second set of input b and it will invoke fn with the merged object of a over b.
fn can be asynchronous function. In that case a Promise holding the result of fn is returned.
See the example below:
const fn = ({a, b, c}) => {
return (a * b) + c
}
const curried = R.partialCurry(fn, {a: 2})
curried({b: 3, c: 10}) // => 16Note that
partialCurryis method specific for Rambda and the method is not part of Ramda's APIYou can read my argumentation for creating partialCurry here
pick
pick(propsToPick: Array
, obj: Object): Object
It returns a partial copy of an obj containing only propsToPick properties.
R.pick(['a', 'c'], {a: 1, b: 2}) // => {a: 1}pipe
pipe(fn1: Function, ... , fnN: Function): any
It performs left-to-right function composition.
const result = R.pipe(
R.filter(val => val > 2),
R.map(a => a * 2)
)([1, 2, 3, 4])
console.log(result) // => [6, 8]pluck
pluck(property: String, arr: Array): Array
It returns list of the values of property taken from the objects in array of objects arr.
R.pluck('a')([{a: 1}, {a: 2}, {b: 3}]) // => [1, 2]prepend
prepend(x: any, arr: Array): Array
It adds x to the start of the array arr.
R.prepend('foo', ['bar', 'baz']) // => ['foo', 'bar', 'baz']prop
prop(propToFind: String, obj: Object): any
It returns undefined or the value of property propToFind in obj
R.prop('x', {x: 100}) // => 100
R.prop('x', {a: 1}) // => undefinedpropEq
propEq(propToFind: String, valueToMatch: any, obj: Object): Boolean
It returns true if obj has property propToFind and its value is equal to valueToMatch
const propToFind = "foo"
const valueToMatch = 0
R.propEq(propToFind, valueToMatch)({foo: 0}) // => true
R.propEq(propToFind, valueToMatch)({foo: 1}) // => falserange
range(start: Number, end: Number): Array
It returns a array of numbers from start(inclusive) to end(exclusive).
R.range(0, 2) // => [0, 1]reduce
reduce(iteratorFn: Function, accumulator: any, array: Array): any
It returns a single item by iterating through the list, successively calling the iterator function iteratorFn and passing it an accumulator value and the current value from the array, and then passing the result to the next call.
The iterator function behaves like the native callback of the Array.prototype.reduce method.
const iteratorFn = (acc, val) => acc + val
R.reduce(iteratorFn, 1, [1, 2, 3]) // => 7reject
reject(fn: Function, arr: Array): Array
It has the opposite effect of R.filter.
It will return those members of arr that return false when applied to function fn.
const fn = x => x % 2 === 1
R.reject(fn, [1, 2, 3, 4]) // => [2, 4]repeat
repeat(valueToRepeat: T, num: Number): Array
R.repeat('foo', 2) // => ['foo', 'foo']replace
replace(strOrRegex: String|Regex, replacer: String, str: String): String
Replace strOrRegex found in str with replacer
R.replace('foo', 'bar', 'foo foo') // => 'bar foo'
R.replace(/foo/, 'bar', 'foo foo') // => 'bar foo'
R.replace(/foo/g, 'bar', 'foo foo') // => 'bar bar'reverse
const arr = [1, 2]
R.reverse(arr)
console.log(arr) // => [2, 1]sort
sort(sortFn: Function, arr: Array): Array
It returns copy of arr sorted by sortFn.
sortFn must return Number
const sortFn = (a, b) => a - b
R.sort(sortFn, [3, 1, 2]) // => [1, 2, 3]sortBy
sortBy(sortFn: Function, arr: Array): Array
It returns copy of arr sorted by sortFn.
sortFn must return value for comparison
const sortFn = obj => obj.foo
R.sortBy(sortFn, [
{foo: 1},
{foo: 0}
])
// => [{foo: 0}, {foo: 1}]split
split(separator: String, str: String): Array
R.split('-', 'a-b-c') // => ['a', 'b', 'c']splitEvery
splitEvery(sliceLength: Number, arrOrString: Array|String): Array
- Splits
arrOrStrinto slices ofsliceLength
R.splitEvery(2, [1, 2, 3]) // => [[1, 2], [3]]
R.splitEvery(3, 'foobar') // => ['foo', 'bar']startsWith
startsWith(x: string, str: String): Boolean
R.startsWith(
'foo',
'foo-bar'
) // => true
R.startsWith(
'bar',
'foo-bar'
) // => falsesubtract
subtract(a: Number, b: Number): Number
R.subtract(3, 1) // => 2T
R.T() // => true
tail
tail(arrOrStr: Array|String): Array|String
- It returns all but the first element of
arrOrStr
R.tail([1, 2, 3]) // => [2, 3]
R.tail('foo') // => 'oo'take
take(num: Number, arrOrStr: Array|String): Array|String
- It returns the first
numelements ofarrOrStr.
R.take(1, ['foo', 'bar']) // => ['foo']
R.take(2, ['foo']) // => 'fo'takeLast
takeLast(num: Number, arrOrStr: Array|String): Array|String
- It returns the last
numelements ofarrOrStr.
R.takeLast(1, ['foo', 'bar']) // => ['bar']
R.takeLast(2, ['foo']) // => 'oo'test
test(regExpression: Regex, str: String): Boolean
- Determines whether
strmatchesregExpression
R.test(/^f/, 'foo') // => true
R.test(/^f/, 'bar') // => falsetimes
times(fn: Function, n: Number): Array
It returns the result of applying function fn over members of range array.
The range array includes numbers between 0 and n(exclusive).
R.times(R.identity, 5); //=> [0, 1, 2, 3, 4]toLower
toLower(str: String): String
R.toLower('FOO') // => 'foo'toString
toString(x: any): String
R.toString([1, 2]) // => '1,2'
toUpper
toUpper(str: String): String
R.toUpper('foo') // => 'FOO'trim
trim(str: String): String
R.trim(' foo ') // => 'foo'type
type(a: any): String
R.type(() => {}) // => "Function"
R.type(async () => {}) // => "Async"
R.type([]) // => "Array"
R.type({}) // => "Object"
R.type('foo') // => "String"
R.type(1) // => "Number"
R.type(true) // => "Boolean"
R.type(null) // => "Null"
R.type(/[A-z]/) // => "RegExp"
const delay = ms => new Promise(resolve => {
setTimeout(function () {
resolve()
}, ms)
})
R.type(delay) // => "Promise"uniq
uniq(arr: Array): Array
It returns a new array containing only one copy of each element in arr.
R.uniq([1, 1, 2, 1]) // => [1, 2]
R.uniq([1, '1']) // => [1, '1']update
update(i: Number, replaceValue: any, arr: Array): Array
It returns a new copy of the arr with the element at i index
replaced with replaceValue.
R.update(0, "foo", ['bar', 'baz']) // => ['foo', baz]values
values(obj: Object): Array
It returns array with of all values in obj.
R.values({a: 1, b: 2}) // => [1, 2]without
without(a: Array, b: Array): Array
It will return a new array based on b array.
This array contains all members of b array, that doesn't exist in a array.
Method R.equals is used to determine the existance of b members in a array.
R.without([1, 2], [1, 2, 3, 4]) // => [3, 4]Benchmark

Tree-shaking

Typings
- Typescript
Rambda's typings are located at ./index.d.ts, so your IDE should be able to pick it up without any additional actions.
- Flowtype
You can use Ramda definitions can be used.
You need to replace declare module ramda with declare module rambda on line 10 and store the file as rambda.js in your flow-typed folder
Changelog
- 1.0.3
R.ifElseaccept also boolean as condition argument - 1.0.2 Remove
typedDefaultToandtypedPathOr| AddR.pickAllandR.none - 1.0.0 Major change as build is now ES6 not ES5 compatible (Related to issue #46)| Making
Rambdafully tree-shakeable| Edit Typescript definition - 0.9.8 Revert to ES5 compatible build - issue #46
- 0.9.7 Refactor for
Rolluptree-shake | RemoveR.padEndandR.padStart - 0.9.6 Close issue #44 -
R.reversemutates the array - 0.9.5 Close issue #45 - invalid Typescript typings
- 0.9.4 Add
R.rejectandR.without(PR#41 PR#42) | Remove 'browser' field inpackage.jsondue to Webpack bug 4674 - 0.9.3 Add
R.forEachandR.times - 0.9.2 Add
Typescriptdefinitions - 0.9.1 Close issue #36 - move current behaviour of
defaultToto a new methodtypedDefaultTo; makedefaultTofollow Ramda spec; addpathOr; addtypedPathOr. - 0.9.0 Add
R.pipePR#35 - 0.8.9 Add
R.isNil - 0.8.8 Migrate to ES modules PR33 | Add R.flip to the API | R.map/filter works with objects
- 0.8.7 Change
WebpackwithRollup- PR29 - 0.8.6 Add
R.tapandR.identity - 0.8.5 Add
R.all,R.allPass,R.both,R.eitherandR.complement - 0.8.4 Learning to run
yarn testbeforeyarn publishthe hard way - 0.8.3 Add
R.always,R.TandR.F - 0.8.2 Add
concat,padStart,padEnd,lastIndexOf,toString,reverse,endsWithandstartsWithmethods - 0.8.1 Add
R.ifElse - 0.8.0 Add
R.not,R.includes| Take string as condition forR.pickandR.omit - 0.7.6 Fix incorrect implementation of
R.values - 0.7.5 Fix incorrect implementation of
R.omit - 0.7.4 issue #13 - Fix
R.curry, which used to return incorrectlyfunctionwhen called with more arguments - 0.7.3 Close issue #9 - Compile to
es2015; Approve PR #10 - addR.addIndexto the API - 0.7.2 Add
Promisesupport forR.type - 0.7.1 Close issue #7 - add
R.reduceto the API - 0.7.0 Close issue #5 - change name of
currytopartialCurry; add new methodcurry, which works just like Ramda'scurry - 0.6.2 Add separate documentation site via
docsify
Browse by category
Function
Math
List
Logic
Object
Relation
String
Contribution guidelines
If you want to add another Ramda method to the API, please feel free to submit a PR .
The only requirement is the new method to have exact or very close implementation compared to the corresponding Ramda method.
I give you example steps of the PR process.
Create a method file in
modulesfolder.
If the new method is R.endsWith, then the created file will be ./modules/endsWith.js
Write the function declaration and function's logic.
function endsWith(x, arrOrStr){
return arrOrStr.endsWith(x)
}Any method, which takes more than one argument, should be curried.
We can use the standard curring used throughout Rambda.
function endsWith(x, arrOrStr){
if(arrOrStr === undefined){
return arrOrStrHolder => endsWith(x, arrOrStrHolder)
}
return arrOrStr.endsWith(x)
}
module.exports = endsWithOr we can also use R.curry, but it is not as performant as the example above.
const curry = require('./curry')
function endsWith(x, arrOrStr){
if(arrOrStr === undefined){
return holder => endsWith(x, arrOrStr)
}
return arrOrStr.endsWith(x)
}
module.exports = curry(endsWith)Edit
rambda.jsfile
Exported methods are sorted alphabetically
exports.dropLast = require("./modules/dropLast")
exports.endsWith = require("./modules/endsWith")
exports.equals = require("./modules/equals")Write your test cases
Create file endsWith.js in folder __tests__
const R = require('../rambda')
test('endsWith', () => {
expect(R.endsWith('oo')('foo')).toBeTruthy()
})Run
yarn testto validate your tests
Edit
./README.mdto add documentation
Note that your documentation should match the pattern visible across ./README.md
Lint your files
yarn run lint modules/endsWith.js
yarn run lint __tests__/endsWith.js
Submit PR
Expect response within 2 days.
Additional info
Running benchmarks
- To run all benchmarks
yarn run benchmark all
- To run single or number of benchmarks
yarn run benchmark add compose filter
Libraries using Rambda
Articles about Rambda