mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2025-10-16 12:05:41 +00:00
2920 lines
82 KiB
TypeScript
2920 lines
82 KiB
TypeScript
import * as R from "ramda";
|
|
|
|
function double(x: number): number {
|
|
return x + x;
|
|
}
|
|
|
|
function shout(x: number): string {
|
|
return x >= 10 ? "big" : "small";
|
|
}
|
|
|
|
class F {
|
|
[k: string]: string;
|
|
x = "X";
|
|
y = "Y";
|
|
}
|
|
class F2 {
|
|
a = 100;
|
|
y = 1;
|
|
|
|
x() {
|
|
}
|
|
|
|
z() {
|
|
}
|
|
}
|
|
|
|
(() => {
|
|
let x: boolean;
|
|
x = R.isArrayLike("a");
|
|
x = R.isArrayLike([1, 2, 3]);
|
|
x = R.isArrayLike([]);
|
|
});
|
|
|
|
(() => {
|
|
R.propIs(Number, "x", {x: 1, y: 2}); // => true
|
|
R.propIs(Number, "x")({x: 1, y: 2}); // => true
|
|
R.propIs(Number)("x", {x: 1, y: 2}); // => true
|
|
R.propIs(Number)("x")({x: 1, y: 2}); // => true
|
|
R.propIs(Number, "x", {x: "foo"}); // => false
|
|
R.propIs(Number, "x", {}); // => false
|
|
});
|
|
|
|
(() => {
|
|
R.type({}); // => "Object"
|
|
R.type(1); // => "Number"
|
|
R.type(false); // => "Boolean"
|
|
R.type("s"); // => "String"
|
|
R.type(null); // => "Null"
|
|
R.type([]); // => "Array"
|
|
R.type(/[A-z]/); // => "RegExp"
|
|
});
|
|
|
|
() => {
|
|
function takesNoArg() {
|
|
return true;
|
|
}
|
|
function takesOneArg(a: number) {
|
|
return [a];
|
|
}
|
|
function takesTwoArgs(a: number, b: number) {
|
|
return [a, b];
|
|
}
|
|
function takesThreeArgs(a: number, b: number, c: number) {
|
|
return [a, b, c];
|
|
}
|
|
|
|
function addFourNumbers(a: number, b: number, c: number, d: number): number {
|
|
return a + b + c + d;
|
|
}
|
|
|
|
function addTenFixedNumbers(a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, k: 9, l: 10): number {
|
|
return a + b + c + d;
|
|
}
|
|
|
|
const x1: (a: number, b: number, c: number, d: number) => number = R.curry(addFourNumbers);
|
|
// because of the current way of currying, the following call results in a type error
|
|
// const x2: Function = R.curry(addFourNumbers)(1,2,4)
|
|
const x3: (c: number, d: number) => number = R.curry(addFourNumbers)(1)(2);
|
|
const x4: (d: number) => number = R.curry(addFourNumbers)(1)(2)(3);
|
|
const y1: number = R.curry(addFourNumbers)(1)(2)(3)(4);
|
|
const y2: number = R.curry(addFourNumbers)(1, 2)(3, 4);
|
|
const y3: number = R.curry(addFourNumbers)(1, 2, 3)(4);
|
|
const y4: number = R.curry(addTenFixedNumbers)(R.__, 1, 2)(0)(3)(R.__, R.__)(R.__, 5)(4)(6, 7)(R.__)(8, R.__, R.__)(9, 10);
|
|
const y5: number = R.curry(addTenFixedNumbers)(R.__, 1, R.__)(R.__, 2)(0, 3)(R.__, 5)(4, R.__)(R.__)(6, R.__, 8, 9, 10)(7);
|
|
|
|
R.nAry(0);
|
|
R.nAry(0, takesNoArg);
|
|
R.nAry(0, takesOneArg);
|
|
R.nAry(1, takesTwoArgs);
|
|
R.nAry(1, takesThreeArgs);
|
|
|
|
const u1: (a: any) => any = R.unary(takesOneArg);
|
|
const u2: (a: any) => any = R.unary(takesTwoArgs);
|
|
const u3: (a: any) => any = R.unary(takesThreeArgs);
|
|
|
|
R.binary(takesTwoArgs);
|
|
R.binary(takesThreeArgs);
|
|
|
|
function addTwoNumbers(a: number, b: number) {
|
|
return a + b;
|
|
}
|
|
|
|
const addTwoNumbersCurried = R.curry(addTwoNumbers);
|
|
|
|
const inc = addTwoNumbersCurried(1);
|
|
const z1: number = inc(2);
|
|
const z2: number = addTwoNumbersCurried(2, 3);
|
|
};
|
|
|
|
() => {
|
|
interface Car { speed?: number;
|
|
}
|
|
interface FastCar { speed: number;
|
|
}
|
|
|
|
function typeGuard(a: number, b: number, c: number, d: number, e: number, car: Car): car is FastCar {
|
|
return car.speed !== undefined;
|
|
}
|
|
|
|
const typeGuardCurried = R.curry(typeGuard);
|
|
|
|
function drive(fastCar: FastCar) {
|
|
}
|
|
|
|
const cars: Car[] = [{speed: 65}, {}];
|
|
for (const car of cars) {
|
|
if (typeGuardCurried(1)(2)(3)(4)(5)(car)) {
|
|
drive(car); // $ExpectError
|
|
// Generic Curry solved a previously non reported issue
|
|
}
|
|
}
|
|
};
|
|
|
|
/** R.__ */
|
|
() => {
|
|
R.concat(R.__, [4, 5, 6])([1, 2, 3]); // [1, 2, 3, 4, 5, 6]
|
|
R.concat(R.__)([4, 5, 6], [1, 2, 3]); // [1, 2, 3, 4, 5, 6]
|
|
|
|
R.contains(R.__, [1, 2, 3])(3); // true
|
|
R.contains<number>(R.__)([1, 2, 3], 3); // true
|
|
|
|
R.divide(R.__)(2, 42); // 21
|
|
R.divide(R.__, 2)(42); // 21
|
|
|
|
R.gt(R.__, 2)(10); // true
|
|
R.gt(R.__)(2, 10); // true
|
|
|
|
R.gte(R.__, 6)(2); // false
|
|
R.gte(R.__)(6, 2); // false
|
|
|
|
R.has(R.__, {x: 0, y: 0})('x'); // true;
|
|
R.has(R.__)({x: 0, y: 0}, 'x'); // true;
|
|
|
|
R.lt(R.__, 5)(10); // false
|
|
R.lt(R.__)(5, 10); // false
|
|
|
|
R.lte(R.__, 2)(1); // true
|
|
R.lte(R.__)(2, 1); // true
|
|
|
|
R.mathMod(R.__, 12)(15); // 3
|
|
R.mathMod(R.__)(12, 15); // 3
|
|
|
|
R.modulo(R.__, 2)(42); // 0
|
|
R.modulo(R.__)(2, 42); // 0
|
|
|
|
R.merge(R.__, {x: 0})({x: 5, y: 2}); // {x: 0, y: 2}
|
|
R.merge(R.__)({x: 0}, {x: 5, y: 2}); // {x: 0, y: 2}
|
|
|
|
R.subtract(R.__, 5)(17); // 12
|
|
R.subtract(R.__)(5, 17); // 12
|
|
};
|
|
|
|
() => {
|
|
const addFour = (a: number) => (b: number) => (c: number) => (d: number) => a + b + c + d;
|
|
const uncurriedAddFour = R.uncurryN<number>(4, addFour);
|
|
const res: number = uncurriedAddFour(1, 2, 3, 4); // => 10
|
|
};
|
|
|
|
() => {
|
|
// coerceArray :: (a|[a]) -> [a]
|
|
const coerceArray = R.unless(R.isArrayLike, R.of);
|
|
const a: number[] = coerceArray([1, 2, 3]); // => [1, 2, 3]
|
|
const b: number[] = coerceArray(1); // => [1]
|
|
};
|
|
|
|
(() => {
|
|
R.nthArg(1)("a", "b", "c"); // => 'b'
|
|
R.nthArg(-1)("a", "b", "c"); // => 'c'
|
|
});
|
|
|
|
() => {
|
|
const fn: (...args: string[]) => string = R.unapply(JSON.stringify);
|
|
const res: string = R.unapply(JSON.stringify)(1, 2, 3); // => '[1,2,3]'
|
|
};
|
|
|
|
() => {
|
|
const a: number = R.until(R.flip(R.gt)(100), R.multiply(2))(1); // => 128
|
|
};
|
|
|
|
() => {
|
|
const truncate = R.when(
|
|
R.propSatisfies(R.flip(R.gt)(10), "length"),
|
|
R.pipe<string, string, string[], string>(R.take(10), R.append("…") as (wrong: any) => string[], R.join(""))
|
|
);
|
|
const a: string = truncate("12345"); // => '12345'
|
|
const b: string = truncate("0123456789ABC"); // => '0123456789…'
|
|
};
|
|
|
|
/* compose */
|
|
() => {
|
|
function double(x: number): number {
|
|
return x + x;
|
|
}
|
|
|
|
function limit10(x: number): boolean {
|
|
return x >= 10;
|
|
}
|
|
|
|
const func: (x: number) => boolean = R.compose(limit10, double);
|
|
const res: boolean = R.compose(limit10, double)(10);
|
|
|
|
const f0 = (s: string) => +s; // string -> number
|
|
const f1 = (n: number) => n === 1; // number -> boolean
|
|
const f2: (s: string) => boolean = R.compose(f1, f0); // string -> boolean
|
|
|
|
// akward example that bounces types between number and string
|
|
const g0 = (list: number[]) => R.map(R.inc, list);
|
|
const g1 = R.dropWhile(R.gt(10));
|
|
const g2 = R.map((i: number) => i > 5 ? "bigger" : "smaller");
|
|
const g3 = R.all((i: string) => i === "smaller");
|
|
const g = R.compose(g3, g2, g1, g0);
|
|
const g_res: boolean = g([1, 2, 10, 13]);
|
|
|
|
// compose with last function taking no params
|
|
const f10 = () => 'str';
|
|
const f11 = (str: string) => str;
|
|
const f12: () => string = R.compose(f11, f10);
|
|
};
|
|
|
|
/* composeK */
|
|
() => {
|
|
const get = (prop: string) => (obj: any): any[] => {
|
|
const propVal = obj[prop];
|
|
if (propVal) {
|
|
return [propVal];
|
|
} else {
|
|
return [];
|
|
}
|
|
};
|
|
|
|
const getStateCode: (input: any) => any[] = R.composeK(
|
|
R.compose((val) => [val], R.toUpper),
|
|
get('state'),
|
|
get('address'),
|
|
get('user'),
|
|
);
|
|
getStateCode({ user: { address: { state: "ny" } } }); // => []
|
|
getStateCode({}); // => []
|
|
|
|
const nextThree = (num: number): number[] => ([num, num + 1, num + 2]);
|
|
const onlyOverNine = (num: number): number[] => num > 9 ? [num] : [];
|
|
const toString = (input: any): string[] => [`${input}`];
|
|
const split = (input: string): string[] => input.split('');
|
|
|
|
const composed: (num: number) => string[] = R.composeK(
|
|
split,
|
|
toString,
|
|
onlyOverNine,
|
|
nextThree,
|
|
);
|
|
};
|
|
|
|
() => {
|
|
const get = (prop: string) => (obj: any): any[] => {
|
|
const propVal = obj[prop];
|
|
if (propVal) {
|
|
return [propVal];
|
|
} else {
|
|
return [];
|
|
}
|
|
};
|
|
|
|
const getStateCode: (input: any) => any[] = R.composeWith(
|
|
R.chain,
|
|
[
|
|
R.compose((val) => [val], R.toUpper),
|
|
get('state'),
|
|
get('address'),
|
|
get('user'),
|
|
],
|
|
);
|
|
getStateCode({ user: { address: { state: "ny" } } }); // => []
|
|
getStateCode({}); // => []
|
|
|
|
const nextThree = (num: number): number[] => ([num, num + 1, num + 2]);
|
|
const onlyOverNine = (num: number): number[] => num > 9 ? [num] : [];
|
|
const toString = (input: any): string[] => [`${input}`];
|
|
const split = (input: string): string[] => input.split('');
|
|
|
|
const composed: (num: number) => string[] = R.composeWith(
|
|
R.chain,
|
|
[
|
|
split,
|
|
toString,
|
|
onlyOverNine,
|
|
nextThree,
|
|
],
|
|
);
|
|
const composed2: (num: number) => string[] = R.composeWith(R.chain)([
|
|
split,
|
|
toString,
|
|
onlyOverNine,
|
|
nextThree,
|
|
]);
|
|
};
|
|
|
|
/* composeP */
|
|
() => {
|
|
interface User {
|
|
name: string;
|
|
followers: string[];
|
|
}
|
|
interface Db {
|
|
users: { [index: string]: User };
|
|
}
|
|
const db: Db = {
|
|
users: {
|
|
JOE: {
|
|
name: 'Joe',
|
|
followers: ['STEVE', 'SUZY']
|
|
}
|
|
}
|
|
};
|
|
|
|
// We'll pretend to do a db lookup which returns a promise
|
|
const lookupUser = (userId: string): Promise<User> => Promise.resolve(db.users[userId]);
|
|
const lookupFollowers = (user: User): Promise<string[]> => Promise.resolve(user.followers);
|
|
lookupUser('JOE').then(lookupFollowers);
|
|
|
|
// followersForUser :: String -> Promise [UserId]
|
|
const followersForUser: (input: string) => Promise<string[]> = R.composeP(lookupFollowers, lookupUser);
|
|
followersForUser('JOE').then(followers => console.log('Followers:', followers));
|
|
// Followers: ["STEVE","SUZY"]
|
|
};
|
|
|
|
/* pipe */
|
|
() => {
|
|
const func: (x: number) => string = R.pipe(double, double, shout);
|
|
const res: string = R.pipe(double, double, shout)(10);
|
|
|
|
const capitalize = (str: string) => R.pipe(
|
|
R.split(""),
|
|
R.adjust(0, R.toUpper),
|
|
R.join("")
|
|
)(str);
|
|
|
|
const f = R.pipe(Math.pow, R.negate, R.inc);
|
|
const fr: number = f(3, 4); // -(3^4) + 1
|
|
|
|
// pipe with first function taking no params
|
|
const f10 = () => 'str';
|
|
const f11 = (str: string) => str;
|
|
const f12: () => string = R.pipe(f10, f11);
|
|
};
|
|
|
|
/* pipeK */
|
|
() => {
|
|
const parseJson = (input: string): any[] => {
|
|
try {
|
|
return [JSON.parse(input)];
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
};
|
|
const get = (prop: string) => (obj: any): any[] => {
|
|
const propVal = obj[prop];
|
|
if (propVal) {
|
|
return [propVal];
|
|
} else {
|
|
return [];
|
|
}
|
|
};
|
|
|
|
const getStateCode: (input: string) => string[] = R.pipeK(
|
|
parseJson,
|
|
get('user'),
|
|
get('address'),
|
|
get('state'),
|
|
R.compose((val) => [val], R.toUpper)
|
|
);
|
|
|
|
getStateCode('{"user":{"address":{"state":"ny"}}}');
|
|
// => Just('NY')
|
|
getStateCode('[Invalid JSON]');
|
|
// => Nothing()
|
|
};
|
|
|
|
/* pipeP */
|
|
() => {
|
|
interface User {
|
|
followers: string[];
|
|
name: string;
|
|
}
|
|
|
|
const db = {
|
|
getUserById(userName: string): Promise<User> {
|
|
return Promise.resolve({
|
|
name: 'Jon',
|
|
followers: [
|
|
'Samwell',
|
|
'Edd',
|
|
'Grenn',
|
|
],
|
|
});
|
|
},
|
|
getFollowers(user: User): Promise<string[]> {
|
|
return Promise.resolve(user.followers);
|
|
},
|
|
};
|
|
const followersForUser: (userName: string) => Promise<string[]> = R.pipeP(db.getUserById, db.getFollowers);
|
|
};
|
|
|
|
() => {
|
|
interface User {
|
|
followers: string[];
|
|
name: string;
|
|
}
|
|
|
|
const db = {
|
|
getUserById(userName: string): Promise<User> {
|
|
return Promise.resolve({
|
|
name: 'Jon',
|
|
followers: [
|
|
'Samwell',
|
|
'Edd',
|
|
'Grenn',
|
|
],
|
|
});
|
|
},
|
|
getFollowers(user: User): Promise<string[]> {
|
|
return Promise.resolve(user.followers);
|
|
},
|
|
};
|
|
const followersForUser: (userName: string) => Promise<string[]> = R.pipeWith(R.then, [db.getUserById, db.getFollowers]);
|
|
const followersForUser2: (userName: string) => Promise<string[]> = R.pipeWith(R.then)([db.getUserById, db.getFollowers]);
|
|
};
|
|
|
|
() => {
|
|
R.invoker(1, "slice")(6, "abcdefghijklm");
|
|
R.invoker(2, "slice")(6)(8, "abcdefghijklm");
|
|
};
|
|
|
|
(() => {
|
|
const range = R.juxt([Math.min, Math.max]);
|
|
range(3, 4, 9, -3); // => [-3, 9]
|
|
|
|
const chopped = R.juxt([R.head, R.last]);
|
|
chopped("longstring"); // => ["l", "g"]
|
|
});
|
|
|
|
function square(x: number) {
|
|
return x * x;
|
|
}
|
|
function add(a: number, b: number) {
|
|
return a + b;
|
|
}
|
|
// Adds any number of arguments together
|
|
function addAll() {
|
|
return 0;
|
|
}
|
|
|
|
// Basic example
|
|
R.useWith(addAll, [double, square]);
|
|
|
|
(() => {
|
|
function printXPlusFive(x: number) {
|
|
console.log(x + 5);
|
|
}
|
|
|
|
R.forEach(printXPlusFive, [1, 2, 3]);
|
|
R.clone([{}, {}, {}]);
|
|
R.clone([1, 2, 3]);
|
|
})();
|
|
|
|
// (() => {
|
|
// function printXPlusFive(x, i) { console.log(i + 5); }
|
|
// R.forEach.idx(printXPlusFive, [{name: 1}, {name: 2}, {name: 3}]);
|
|
// })();
|
|
|
|
function i(x: number) {
|
|
return x;
|
|
}
|
|
R.times(i, 5);
|
|
|
|
(() => {
|
|
function triple(x: number): number {
|
|
return x * 3;
|
|
}
|
|
|
|
function square(x: number): number {
|
|
return x * x;
|
|
}
|
|
|
|
const squareThenDoubleThenTriple = R.pipe(square, double, triple);
|
|
squareThenDoubleThenTriple(5); // => 150
|
|
})();
|
|
|
|
(() => {
|
|
function multiply(a: number, b: number): number {
|
|
return a * b;
|
|
}
|
|
|
|
const double = R.partial<number>(multiply, [2]);
|
|
double(2); // => 4
|
|
|
|
function greet(salutation: string, title: string, firstName: string, lastName: string) {
|
|
return `${salutation}, ${title} ${firstName} ${lastName}!`;
|
|
}
|
|
|
|
const sayHello = R.partial(greet, ["Hello"]);
|
|
const sayHelloToMs = R.partial(sayHello, ["Ms."]);
|
|
sayHelloToMs("Jane", "Jones"); // => 'Hello, Ms. Jane Jones!'
|
|
|
|
const greetMsJaneJones = R.partialRight(greet, ["Ms.", "Jane", "Jones"]);
|
|
greetMsJaneJones("Hello"); // => 'Hello, Ms. Jane Jones!'
|
|
})();
|
|
|
|
(() => {
|
|
interface Vector {
|
|
x: number;
|
|
y: number;
|
|
}
|
|
|
|
let numberOfCalls = 0;
|
|
|
|
function vectorSum(a: Vector, b: Vector): Vector {
|
|
numberOfCalls += 1;
|
|
return {
|
|
x: a.x + b.x,
|
|
y: a.y + b.y
|
|
};
|
|
}
|
|
|
|
const memoVectorSum = R.memoizeWith((a, b) => JSON.stringify([a, b]), vectorSum);
|
|
|
|
memoVectorSum({ x: 1, y: 1 }, { x: 2, y: 2 }); // => { x: 3, y: 3 }
|
|
numberOfCalls; // => 1
|
|
memoVectorSum({ x: 1, y: 1 }, { x: 2, y: 2 }); // => { x: 3, y: 3 }
|
|
numberOfCalls; // => 1
|
|
memoVectorSum({ x: 1, y: 2 }, { x: 2, y: 3 }); // => { x: 3, y: 5 }
|
|
numberOfCalls; // => 2
|
|
|
|
// Note that argument order matters
|
|
memoVectorSum({ x: 2, y: 3 }, { x: 1, y: 2 }); // => { x: 3, y: 5 }
|
|
numberOfCalls; // => 3
|
|
})();
|
|
|
|
(() => {
|
|
const addOneOnce = R.once((x: number) => x + 1);
|
|
addOneOnce(10); // => 11
|
|
addOneOnce(addOneOnce(50)); // => 11
|
|
|
|
const str = R.once<string>(() => 'test')();
|
|
})();
|
|
|
|
(() => {
|
|
const slashify = R.wrap(R.flip(R.add)("/"), (f: (x: string) => string, x: string) => R.match(/\/$/, x) ? x : f(x));
|
|
|
|
slashify("a"); // => 'a/'
|
|
slashify("a/"); // => 'a/'
|
|
})();
|
|
|
|
(() => {
|
|
const numbers = [1, 2, 3];
|
|
R.reduce((a, b) => a + b, 10, numbers); // => 16;
|
|
})();
|
|
|
|
(() => {
|
|
const plus3 = R.add(3);
|
|
})();
|
|
|
|
(() => {
|
|
const pairs = [["a", 1], ["b", 2], ["c", 3]];
|
|
|
|
function flattenPairs(pair: [string, number], acc: Array<string|number>): Array<string|number> {
|
|
return acc.concat(pair);
|
|
}
|
|
|
|
R.reduceRight(flattenPairs, [], pairs); // => [ 'c', 3, 'b', 2, 'a', 1 ]
|
|
})();
|
|
|
|
(() => {
|
|
const values = {x: 1, y: 2, z: 3};
|
|
|
|
function prependKeyAndDouble(num: number, key: string, obj: any) {
|
|
return key + (num * 2);
|
|
}
|
|
|
|
R.mapObjIndexed(prependKeyAndDouble, values); // => { x: 'x2', y: 'y4', z: 'z6' }
|
|
});
|
|
|
|
(() => {
|
|
const testObject: {
|
|
[key: string]: Error
|
|
} = {
|
|
hello: new Error('hello'),
|
|
};
|
|
const errorMessages = R.mapObjIndexed(
|
|
function test(value, key) {
|
|
// value should be inferred.
|
|
return value.message + String(key);
|
|
}, testObject);
|
|
console.log(errorMessages);
|
|
});
|
|
|
|
(() => {
|
|
const a: number[] = R.ap([R.multiply(2), R.add(3)], [1, 2, 3]); // => [2, 4, 6, 4, 5, 6]
|
|
const b: number[][] = R.of([1]); // => [[1]]
|
|
const c: number[] = R.of(1);
|
|
});
|
|
|
|
() => {
|
|
const a1 = R.empty([1, 2, 3, 4, 5]); // => []
|
|
const a2 = R.empty([1, 2, 3]); // => []
|
|
const a3 = R.empty("unicorns"); // => ''
|
|
const a4 = R.empty({x: 1, y: 2}); // => {}
|
|
};
|
|
|
|
(() => {
|
|
R.length([1, 2, 3]); // => 3
|
|
});
|
|
|
|
(() => {
|
|
function isEven(n: number) {
|
|
return n % 2 === 0;
|
|
}
|
|
|
|
const filterIndexed = R.addIndex(R.filter);
|
|
|
|
R.filter(isEven, [1, 2, 3, 4]); // => [2, 4]
|
|
R.filter(isEven, { a: 0, b: 1 }); // => { a: 0 }
|
|
|
|
function lastTwo(val: number, idx: number, list: number[]) {
|
|
return list.length - idx <= 2;
|
|
}
|
|
|
|
filterIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); // => [0, 9]
|
|
|
|
function isOdd(n: number) {
|
|
return n % 2 === 1;
|
|
}
|
|
|
|
R.reject(isOdd, [1, 2, 3, 4]); // => [2, 4]
|
|
R.reject(isOdd, { a: 0, b: 1 }); // => { a: 0 }
|
|
});
|
|
(() => {
|
|
function isNotFour(x: number) {
|
|
return !(x === 4);
|
|
}
|
|
|
|
R.takeWhile(isNotFour, [1, 2, 3, 4]); // => [1, 2, 3]
|
|
R.take(2, [1, 2, 3, 4]); // => [1, 2]
|
|
});
|
|
(() => {
|
|
function f(n: number): false | [number, number] {
|
|
return n > 50 ? false : [-n, n + 10];
|
|
}
|
|
|
|
const a = R.unfold(f, 10); // => [-10, -20, -30, -40, -50]
|
|
const b = R.unfold(f); // => [-10, -20, -30, -40, -50]
|
|
const c = b(10);
|
|
});
|
|
/*****************************************************************
|
|
* Function category
|
|
*/
|
|
() => {
|
|
function mergeThree(a: number, b: number, c: number): number[] {
|
|
return (new Array<number>()).concat(a, b, c);
|
|
}
|
|
|
|
mergeThree(1, 2, 3); // => [1, 2, 3]
|
|
const flipped = R.flip(mergeThree);
|
|
flipped(1, 2, 3); // => [2, 1, 3]
|
|
};
|
|
|
|
/*********************
|
|
* List category
|
|
*/
|
|
() => {
|
|
const lessThan2 = R.flip(R.lt)(2);
|
|
const lessThan3 = R.flip(R.lt)(3);
|
|
R.all(lessThan2)([1, 2]); // => false
|
|
R.all(lessThan3)([1, 2]); // => true
|
|
};
|
|
|
|
() => {
|
|
const lessThan0 = R.flip(R.lt)(0);
|
|
const lessThan2 = R.flip(R.lt)(2);
|
|
R.any(lessThan0)([1, 2]); // => false
|
|
R.any(lessThan2)([1, 2]); // => true
|
|
};
|
|
|
|
() => {
|
|
R.aperture(2, [1, 2, 3, 4, 5]); // => [[1, 2], [2, 3], [3, 4], [4, 5]]
|
|
R.aperture(3, [1, 2, 3, 4, 5]); // => [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
|
|
R.aperture(7, [1, 2, 3, 4, 5]); // => []
|
|
R.aperture(7)([1, 2, 3, 4, 5]); // => []
|
|
|
|
const res1: Array<[number, number]> = R.aperture(2, [1, 2, 3, 4, 5]);
|
|
const res2: number[][] = R.aperture(11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
|
|
};
|
|
|
|
() => {
|
|
R.append("tests", ["write", "more"]); // => ['write', 'more', 'tests']
|
|
R.append("tests")(["write", "more"]); // => ['write', 'more', 'tests']
|
|
R.append("tests", []); // => ['tests']
|
|
};
|
|
|
|
() => {
|
|
function duplicate(n: number) {
|
|
return [n, n];
|
|
}
|
|
|
|
R.chain(duplicate, [1, 2, 3]); // => [1, 1, 2, 2, 3, 3]
|
|
R.chain(duplicate)([1, 2, 3]); // => [1, 1, 2, 2, 3, 3]
|
|
};
|
|
|
|
() => {
|
|
R.clamp(1, 10, -1); // => 1
|
|
R.clamp(1, 10)(11); // => 10
|
|
R.clamp(1)(10, 4); // => 4
|
|
R.clamp("a", "d", "e"); // => 'd'
|
|
};
|
|
|
|
() => {
|
|
R.concat([], []); // => []
|
|
R.concat([4, 5, 6], [1, 2, 3]); // => [4, 5, 6, 1, 2, 3]
|
|
R.concat([4, 5, 6])([1, 2, 3]); // => [4, 5, 6, 1, 2, 3]
|
|
R.concat("ABC")("DEF"); // 'ABCDEF'
|
|
};
|
|
|
|
() => {
|
|
R.contains(3)([1, 2, 3]); // => true
|
|
R.contains(3, [1, 2, 3]); // => true
|
|
R.contains(4)([1, 2, 3]); // => false
|
|
R.contains({})([{}, {}]); // => false
|
|
const obj = {};
|
|
R.contains(obj)([{}, obj, {}]); // => true
|
|
};
|
|
|
|
() => {
|
|
R.drop(3, [1, 2, 3, 4, 5, 6, 7]); // => [4,5,6,7]
|
|
R.drop(3)([1, 2, 3, 4, 5, 6, 7]); // => [4,5,6,7]
|
|
R.drop(3, "ramda"); // => 'ram'
|
|
R.drop(3)("ramda"); // => 'ram'
|
|
};
|
|
|
|
(() => {
|
|
R.dropLast(1, ["foo", "bar", "baz"]); // => ['foo', 'bar']
|
|
R.dropLast(2)(["foo", "bar", "baz"]); // => ['foo']
|
|
R.dropLast(3, "ramda"); // => 'ra'
|
|
R.dropLast(3)("ramda"); // => 'ra'
|
|
});
|
|
|
|
(() => {
|
|
const lteThree = (x: number) => x <= 3;
|
|
R.dropLastWhile(lteThree, [1, 2, 3, 4, 3, 2, 1]); // => [1, 2, 3, 4]
|
|
});
|
|
|
|
(() => {
|
|
R.dropRepeats([1, 1, 1, 2, 3, 4, 4, 2, 2]); // => [1, 2, 3, 4, 2]
|
|
});
|
|
|
|
(() => {
|
|
const l = [1, -1, 1, 3, 4, -4, -4, -5, 5, 3, 3];
|
|
const x: number[] = R.dropRepeatsWith(R.eqBy(Math.abs), l); // => [1, 3, 4, -5, 3]
|
|
});
|
|
|
|
() => {
|
|
function lteTwo(x: number) {
|
|
return x <= 2;
|
|
}
|
|
|
|
R.dropWhile(lteTwo, [1, 2, 3, 4]); // => [3, 4]
|
|
R.dropWhile(lteTwo)([1, 2, 3, 4]); // => [3, 4]
|
|
};
|
|
|
|
() => {
|
|
function isEven(n: number) {
|
|
return n % 2 === 0;
|
|
}
|
|
|
|
const filterEven = R.filter(isEven);
|
|
const objA: R.Dictionary<number> = filterEven({ a: 0, b: 1 }); // => { a: 0 }
|
|
const listA: number[] = filterEven([0, 1]); // => [0]
|
|
|
|
const rejectEven = R.reject(isEven);
|
|
const objB: R.Dictionary<number> = rejectEven({ a: 0, b: 1 }); // => { b: 1 }
|
|
const listB: number[] = rejectEven([0, 1]); // => [1]
|
|
};
|
|
|
|
() => {
|
|
function isEven(n: number) {
|
|
return n % 2 === 0;
|
|
}
|
|
|
|
const a: R.Dictionary<number> = R.pipe(
|
|
R.filter<number, 'object'>(isEven),
|
|
)({ a: 0, b: 1 }); // => { a: 0 }
|
|
|
|
const b: number[] = R.pipe(
|
|
R.filter<number, 'array'>(isEven),
|
|
)([0, 1]); // => [0]
|
|
|
|
const c: R.Dictionary<number> = R.pipe(
|
|
R.reject<number, 'object'>(isEven),
|
|
)({ a: 0, b: 1 }); // => { b: 1 }
|
|
|
|
const d: number[] = R.pipe(
|
|
R.reject<number, 'array'>(isEven),
|
|
)([0, 1]); // => [1]
|
|
};
|
|
|
|
() => {
|
|
function lastTwo(val: number, idx: number, list: number[]) {
|
|
return list.length - idx <= 2;
|
|
}
|
|
|
|
const filterIndexed = R.addIndex(R.filter);
|
|
|
|
filterIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); // => [0, 9]
|
|
const lastTwoFn = filterIndexed(lastTwo);
|
|
lastTwoFn([8, 6, 7, 5, 3, 0, 9]);
|
|
};
|
|
|
|
() => {
|
|
const xs = [{a: 1}, {a: 2}, {a: 3}];
|
|
R.find(R.propEq("a", 2))(xs); // => {a: 2}
|
|
R.find(R.propEq("a", 4))(xs); // => undefined
|
|
};
|
|
|
|
() => {
|
|
const xs = [{a: 1}, {a: 2}, {a: 3}];
|
|
R.findIndex(R.propEq("a", 2))(xs); // => 1
|
|
R.findIndex(R.propEq("a", 4))(xs); // => -1
|
|
|
|
R.findIndex((x: number) => x === 1, [1, 2, 3]);
|
|
};
|
|
|
|
() => {
|
|
const xs = [{a: 1, b: 0}, {a: 1, b: 1}];
|
|
R.findLast(R.propEq("a", 1))(xs); // => {a: 1, b: 1}
|
|
R.findLast(R.propEq("a", 4))(xs); // => undefined
|
|
};
|
|
|
|
() => {
|
|
const xs = [{a: 1, b: 0}, {a: 1, b: 1}];
|
|
R.findLastIndex(R.propEq("a", 1))(xs); // => 1
|
|
R.findLastIndex(R.propEq("a", 4))(xs); // => -1
|
|
R.findLastIndex((x: number) => x === 1, [1, 2, 3]);
|
|
};
|
|
|
|
() => {
|
|
const testPath = ["x", 0, "y"];
|
|
const testObj = {x: [{y: 2, z: 3}, {y: 4, z: 5}]};
|
|
|
|
R.pathEq(testPath, 2, testObj); // => true
|
|
R.pathEq(testPath, 2)(testObj); // => true
|
|
R.pathEq(testPath)(2)(testObj); // => true
|
|
R.pathEq(testPath)(2, testObj); // => true
|
|
|
|
const user1 = {address: {zipCode: 90210}};
|
|
const user2 = {address: {zipCode: 55555}};
|
|
const user3 = {name: "Bob"};
|
|
const users = [user1, user2, user3];
|
|
const isFamous = R.pathEq(["address", "zipCode"], 90210);
|
|
R.filter(isFamous, users); // => [ user1 ]
|
|
};
|
|
|
|
() => {
|
|
const coll = [{ type: 'BUY' }, { type: 'SELL' }, { type: 'BUY' }];
|
|
const typeIs = R.propEq('type');
|
|
const isBuy = typeIs('BUY');
|
|
R.filter(isBuy, coll); // [{ type: 'BUY' }, { type: 'BUY' }]
|
|
};
|
|
|
|
() => {
|
|
const xs: { [key: string]: string } = {a: "1", b: "0"};
|
|
R.propEq("a", "1", xs); // => true
|
|
R.propEq("a", "4", xs); // => false
|
|
};
|
|
|
|
() => {
|
|
const xs: { [key: string]: number } = {a: 1, b: 0};
|
|
R.propEq("a", 1, xs); // => true
|
|
R.propEq("a", 4, xs); // => false
|
|
};
|
|
|
|
() => {
|
|
const xs = {a: "1", b: "0"};
|
|
R.propEq("a", "1", xs); // => true
|
|
R.propEq("a", "4", xs); // => false
|
|
};
|
|
|
|
() => {
|
|
const xs = {a: 1, b: 0};
|
|
R.propEq("a", 1, xs); // => true
|
|
R.propEq("a", 4, xs); // => false
|
|
};
|
|
|
|
interface Obj {
|
|
a: number;
|
|
b: number;
|
|
}
|
|
|
|
() => {
|
|
const xs: Obj = {a: 1, b: 0};
|
|
R.propEq("a", 1, xs); // => true
|
|
R.propEq("a", 4, xs); // => false
|
|
};
|
|
|
|
() => {
|
|
R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]);
|
|
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
|
};
|
|
|
|
() => {
|
|
function printXPlusFive(x: number) {
|
|
console.log(x + 5);
|
|
}
|
|
|
|
R.forEach(printXPlusFive, [1, 2, 3]); // => [1, 2, 3]
|
|
R.forEach(printXPlusFive)([1, 2, 3]); // => [1, 2, 3]
|
|
// -> 6
|
|
// -> 7
|
|
// -> 8
|
|
};
|
|
|
|
() => {
|
|
function plusFive(num: number, idx: number, list: number[]) {
|
|
list[idx] = num + 5;
|
|
}
|
|
|
|
R.addIndex(R.forEach)(plusFive)([1, 2, 3]); // => [6, 7, 8]
|
|
};
|
|
|
|
() => {
|
|
const byGrade = R.groupBy((student: { score: number; name: string }) => {
|
|
const score = student.score;
|
|
return score < 65 ? "F" :
|
|
score < 70 ? "D" :
|
|
score < 80 ? "C" :
|
|
score < 90 ? "B" : "A";
|
|
});
|
|
const students = [{name: "Abby", score: 84},
|
|
{name: "Eddy", score: 58},
|
|
{name: "Jack", score: 69}];
|
|
byGrade(students);
|
|
};
|
|
|
|
() => {
|
|
interface MyObject {
|
|
id: string;
|
|
quantity: number;
|
|
}
|
|
|
|
const reduceWithCombinedQuantities = (items: MyObject[]) =>
|
|
items.reduce<MyObject>(
|
|
(acc, item) => ({...item, quantity: acc.quantity + item.quantity}),
|
|
{id: '', quantity: 0},
|
|
);
|
|
|
|
const combineMyObjects = R.pipe(
|
|
R.groupBy<MyObject>(s => s.id),
|
|
R.values,
|
|
R.map(reduceWithCombinedQuantities),
|
|
);
|
|
|
|
const combined = combineMyObjects([
|
|
{id: 'foo', quantity: 4},
|
|
{id: 'bar', quantity: 3},
|
|
{id: 'foo', quantity: 2},
|
|
]);
|
|
|
|
return {
|
|
id: combined[0].id,
|
|
quantity: combined[0].quantity
|
|
};
|
|
};
|
|
|
|
() => {
|
|
R.groupWith(R.equals)([0, 1, 1, 2, 3, 5, 8, 13, 21]);
|
|
|
|
R.groupWith(R.equals, [0, 1, 1, 2, 3, 5, 8, 13, 21]);
|
|
// [[0], [1, 1], [2, 3, 5, 8, 13, 21]]
|
|
|
|
R.groupWith((a: number, b: number) => a % 2 === b % 2, [0, 1, 1, 2, 3, 5, 8, 13, 21]);
|
|
// [[0], [1, 1], [2], [3, 5], [8], [13, 21]]
|
|
|
|
const isVowel = (a: string) => R.contains(a, "aeiou") ? a : "";
|
|
R.groupWith(R.eqBy<string>(isVowel), "aestiou");
|
|
// ['ae', 'st', 'iou']
|
|
};
|
|
|
|
() => {
|
|
R.head(["fi", "fo", "fum"]); // => 'fi'
|
|
R.head([10, "ten"]); // => 10
|
|
R.head(["10", 10]); // => '10'
|
|
R.head("abc"); // => 'a'
|
|
R.head(""); // => ''
|
|
};
|
|
|
|
(() => {
|
|
interface Book {
|
|
id: string;
|
|
title: string;
|
|
}
|
|
const list: Book[] = [{id: "xyz", title: "A"}, {id: "abc", title: "B"}];
|
|
const a1 = R.indexBy(R.prop("id"), list);
|
|
// Typescript 3.3 incorrectly gives `a2: {}`, 3.4 gives an error instead.
|
|
// const a2 = R.indexBy(R.prop("id"))(list);
|
|
const a3 = R.indexBy<{ id: string }>(R.prop("id"))(list);
|
|
const a4 = R.indexBy(R.prop<"id", string>("id"))(list);
|
|
const a5 = R.indexBy<{ id: string }>(R.prop<"id", string>("id"))(list);
|
|
|
|
const titlesIndexedByTitles: { [k: string]: string } = R.pipe(
|
|
R.map((x: Book) => x.title),
|
|
R.indexBy(x => x),
|
|
)(list);
|
|
});
|
|
|
|
() => {
|
|
R.includes('ba', 'banana'); // => true
|
|
R.includes('ba')('kiwi'); // => false
|
|
R.includes('ma', ['ma', 'ng', 'o']); // => true
|
|
R.includes('ma')(['li', 'me']); // => false
|
|
R.includes(8, [1, 8, 9, 17]); // => true
|
|
R.includes(1)([2, 3, 5, 8]); // => false
|
|
};
|
|
|
|
() => {
|
|
R.indexOf(3, [1, 2, 3, 4]); // => 2
|
|
R.indexOf(10)([1, 2, 3, 4]); // => -1
|
|
};
|
|
|
|
() => {
|
|
R.init(["fi", "fo", "fum"]); // => ['fi', 'fo']
|
|
R.init("abc"); // => 'ab'
|
|
R.init(""); // => ''
|
|
};
|
|
|
|
() => {
|
|
R.insert(2, 5, [1, 2, 3, 4]); // => [1,2,5,3,4]
|
|
R.insert(2)(5, [1, 2, 3, 4]); // => [1,2,5,3,4]
|
|
R.insert(2, 5)([1, 2, 3, 4]); // => [1,2,5,3,4]
|
|
};
|
|
|
|
() => {
|
|
R.insertAll(2, [10, 11, 12], [1, 2, 3, 4]);
|
|
R.insertAll(2)([10, 11, 12], [1, 2, 3, 4]);
|
|
R.insertAll(2, [10, 11, 12])([1, 2, 3, 4]);
|
|
};
|
|
|
|
() => {
|
|
const numbers = [1, 2, 3, 4];
|
|
const transducer = R.compose(R.map(R.add(1)), R.take(2));
|
|
|
|
R.into([], transducer, numbers); // => [2, 3]
|
|
|
|
const intoArray = R.into([]);
|
|
intoArray(transducer, numbers); // => [2, 3]
|
|
};
|
|
|
|
() => {
|
|
const spacer = R.join(" ");
|
|
spacer(["a", 2, 3.4]); // => 'a 2 3.4'
|
|
R.join("|", [1, 2, 3]); // => '1|2|3'
|
|
};
|
|
|
|
() => {
|
|
R.last(["fi", "fo", "fum"]); // => 'fum'
|
|
R.last("abc"); // => 'c'
|
|
R.last(""); // => ''
|
|
};
|
|
|
|
() => {
|
|
R.lastIndexOf(3, [-1, 3, 3, 0, 1, 2, 3, 4]); // => 6
|
|
R.lastIndexOf(10, [1, 2, 3, 4]); // => -1
|
|
};
|
|
|
|
() => {
|
|
R.length([]); // => 0
|
|
R.length([1, 2, 3]); // => 3
|
|
};
|
|
|
|
() => {
|
|
const headLens = R.lensIndex(0);
|
|
headLens([10, 20, 30, 40]); // => 10
|
|
headLens.set("mu", [10, 20, 30, 40]); // => ['mu', 20, 30, 40]
|
|
R.view(headLens, ["a", "b", "c"]); // => 'a'
|
|
R.set(headLens, "x", ["a", "b", "c"]); // => ['x', 'b', 'c']
|
|
R.over(headLens, R.toUpper, ["a", "b", "c"]); // => ['A', 'b', 'c']
|
|
};
|
|
|
|
() => {
|
|
function double(x: number) {
|
|
return x * 2;
|
|
}
|
|
|
|
R.map(double, [1, 2, 3]); // => [2, 4, 6]
|
|
|
|
// functor
|
|
const numberFunctor = {
|
|
map: <U>(fn: (c: number) => U) => {
|
|
const chars = "Ifmmp!Xpsme".split("");
|
|
return chars.map(char => fn(char.charCodeAt(0)));
|
|
}
|
|
};
|
|
R.map((x: number) => x - 1, numberFunctor); // => "Hello World"
|
|
};
|
|
|
|
() => {
|
|
interface A {
|
|
a: number;
|
|
b: number;
|
|
}
|
|
|
|
interface B {
|
|
a: string;
|
|
b: string;
|
|
}
|
|
|
|
R.map<A, A>(R.inc, {a: 1, b: 2});
|
|
R.map<A, B>(R.toString, {a: 1, b: 2});
|
|
|
|
R.map<A, A>(R.inc)({a: 1, b: 2});
|
|
R.map<A, B>(R.toString)({a: 1, b: 2});
|
|
};
|
|
|
|
() => {
|
|
const digits = ["1", "2", "3", "4"];
|
|
|
|
function append(a: string, b: string): [string, string] {
|
|
return [a + b, a + b];
|
|
}
|
|
|
|
R.mapAccum(append, "0", digits); // => ['01234', ['01', '012', '0123', '01234']]
|
|
R.mapAccum(append)("0", digits); // => ['01234', ['01', '012', '0123', '01234']]
|
|
R.mapAccum(append, "0")(digits); // => ['01234', ['01', '012', '0123', '01234']]
|
|
};
|
|
|
|
() => {
|
|
const digits = ["1", "2", "3", "4"];
|
|
|
|
function append(a: string, b: string): [string, string] {
|
|
return [a + b, a + b];
|
|
}
|
|
|
|
R.mapAccumRight(append, "0", digits); // => ['04321', ['04321', '0432', '043', '04']]
|
|
R.mapAccumRight(append)("0", digits); // => ['04321', ['04321', '0432', '043', '04']]
|
|
R.mapAccumRight(append, "0")(digits); // => ['04321', ['04321', '0432', '043', '04']]
|
|
};
|
|
|
|
() => {
|
|
function squareEnds(elt: number, idx: number, list: number[]) {
|
|
if (idx === 0 || idx === list.length - 1) {
|
|
return elt * elt;
|
|
}
|
|
return elt;
|
|
}
|
|
|
|
R.addIndex(R.map)(squareEnds, [8, 5, 3, 0, 9]); // => [64, 5, 3, 0, 81]
|
|
R.addIndex(R.map)(squareEnds)([8, 5, 3, 0, 9]); // => [64, 5, 3, 0, 81]
|
|
};
|
|
|
|
() => {
|
|
const sampleList = ['a', 'b', 'c', 'd', 'e', 'f'];
|
|
|
|
R.move<string>(0, 2, sampleList); // => ['b', 'c', 'a', 'd', 'e', 'f']
|
|
R.move<string>(-1, 0, sampleList); // => ['f', 'a', 'b', 'c', 'd', 'e'] list rotation
|
|
|
|
const moveCurried1 = R.move(0, 2);
|
|
moveCurried1<string>(sampleList); // => ['b', 'c', 'a', 'd', 'e', 'f']
|
|
|
|
const moveCurried2 = R.move(0);
|
|
moveCurried2<string>(2, sampleList); // => ['b', 'c', 'a', 'd', 'e', 'f']
|
|
|
|
const moveCurried3 = R.move(0);
|
|
const moveCurried4 = moveCurried3(2);
|
|
moveCurried4<string>(sampleList); // => ['b', 'c', 'a', 'd', 'e', 'f']
|
|
};
|
|
|
|
() => {
|
|
R.none(R.isNaN, [1, 2, 3]); // => true
|
|
R.none(R.isNaN, [1, 2, 3, NaN]); // => false
|
|
R.none(R.isNaN)([1, 2, 3, NaN]); // => false
|
|
};
|
|
|
|
() => {
|
|
const list = ["foo", "bar", "baz", "quux"];
|
|
R.nth(1, list); // => 'bar'
|
|
R.nth(-1, list); // => 'quux'
|
|
R.nth(-99, list); // => undefined
|
|
R.nth(-99)(list); // => undefined
|
|
};
|
|
|
|
() => {
|
|
R.partition(R.contains("s"), ["sss", "ttt", "foo", "bars"]);
|
|
R.partition(R.contains("s"))(["sss", "ttt", "foo", "bars"]);
|
|
R.partition((x: number) => x > 2, [1, 2, 3, 4]);
|
|
R.partition((x: number) => x > 2)([1, 2, 3, 4]);
|
|
};
|
|
|
|
() => {
|
|
const a = R.pluck("a")([{a: 1}, {a: 2}]); // => [1, 2]
|
|
const b = R.pluck(0)([[1, 2], [3, 4]]); // => [1, 3]
|
|
};
|
|
|
|
() => {
|
|
R.prepend("fee", ["fi", "fo", "fum"]); // => ['fee', 'fi', 'fo', 'fum']
|
|
R.prepend("fee")(["fi", "fo", "fum"]); // => ['fee', 'fi', 'fo', 'fum']
|
|
};
|
|
|
|
() => {
|
|
R.range(1, 5); // => [1, 2, 3, 4]
|
|
R.range(50)(53); // => [50, 51, 52]
|
|
};
|
|
|
|
() => {
|
|
const numbers = [1, 2, 3];
|
|
|
|
R.reduce((a, b) => a + b, 10, numbers); // => 16
|
|
R.reduce(add)(10, numbers); // => 16
|
|
R.reduce<number, number>((a, b) => a + b, 10)(numbers); // => 16
|
|
};
|
|
|
|
interface Student {
|
|
name: string;
|
|
score: number;
|
|
}
|
|
|
|
() => {
|
|
const reduceToNamesBy = R.reduceBy((acc: string[], student: Student) => acc.concat(student.name), []);
|
|
const namesByGrade = reduceToNamesBy((student) => {
|
|
const score = student.score;
|
|
return score < 65 ? "F" :
|
|
score < 70 ? "D" :
|
|
score < 80 ? "C" :
|
|
score < 90 ? "B" : "A";
|
|
});
|
|
const students = [{name: "Lucy", score: 92},
|
|
{name: "Drew", score: 85},
|
|
{name: "Bart", score: 62}];
|
|
const names = namesByGrade(students);
|
|
// {
|
|
// 'A': ['Lucy'],
|
|
// 'B': ['Drew']
|
|
// 'F': ['Bart']
|
|
// }
|
|
};
|
|
|
|
() => {
|
|
const reduceIndexed = R.addIndex(R.reduce);
|
|
const letters = ["a", "b", "c"];
|
|
|
|
function objectify(accObject: { [elem: string]: number }, elem: string, idx: number, list: string[]) {
|
|
accObject[elem] = idx;
|
|
return accObject;
|
|
}
|
|
|
|
reduceIndexed(objectify, {}, letters); // => { 'a': 0, 'b': 1, 'c': 2 }
|
|
reduceIndexed(objectify)({}, letters); // => { 'a': 0, 'b': 1, 'c': 2 }
|
|
reduceIndexed(objectify, {})(letters); // => { 'a': 0, 'b': 1, 'c': 2 }
|
|
};
|
|
|
|
interface KeyValuePair<K, V> extends Array<K | V> {
|
|
0: K;
|
|
1: V;
|
|
}
|
|
type Pair = KeyValuePair<string, number>;
|
|
|
|
() => {
|
|
const pairs: Pair[] = [["a", 1], ["b", 2], ["c", 3]];
|
|
|
|
function flattenPairs(pair: Pair, acc: Array<string|number>): Array<string|number> {
|
|
return acc.concat(pair);
|
|
}
|
|
|
|
R.reduceRight(flattenPairs, [], pairs); // => [ 'c', 3, 'b', 2, 'a', 1 ]
|
|
R.reduceRight(flattenPairs, [])(pairs); // => [ 'c', 3, 'b', 2, 'a', 1 ]
|
|
R.reduceRight(flattenPairs)([], pairs); // => [ 'c', 3, 'b', 2, 'a', 1 ]
|
|
};
|
|
|
|
() => {
|
|
const isOdd = (acc: number, x: number) => x % 2 === 1;
|
|
|
|
const xs: number[] = [1, 3, 5, 60, 777, 800];
|
|
R.reduceWhile(isOdd, R.add, 0, xs); // => 9
|
|
R.reduceWhile(isOdd)(R.add, 0, xs); // => 9
|
|
R.reduceWhile(isOdd)(R.add, 0)(xs); // => 9
|
|
R.reduceWhile(isOdd)(R.add)(0, xs); // => 9
|
|
R.reduceWhile(isOdd)(R.add)(0)(xs); // => 9
|
|
R.reduceWhile(isOdd, R.add)(0, xs); // => 9
|
|
R.reduceWhile(isOdd, R.add)(0)(xs); // => 9
|
|
R.reduceWhile(isOdd, R.add, 0)(xs); // => 9
|
|
|
|
const ys: number[] = [];
|
|
R.reduceWhile(isOdd, R.add, 111, ys); // => 111
|
|
R.reduceWhile(isOdd)(R.add, 111, ys); // => 111
|
|
R.reduceWhile(isOdd)(R.add, 111)(ys); // => 111
|
|
R.reduceWhile(isOdd)(R.add)(111, ys); // => 111
|
|
R.reduceWhile(isOdd)(R.add)(111)(ys); // => 111
|
|
R.reduceWhile(isOdd, R.add)(111, ys); // => 111
|
|
R.reduceWhile(isOdd, R.add)(111)(ys); // => 111
|
|
R.reduceWhile(isOdd, R.add, 111)(ys); // => 111
|
|
};
|
|
|
|
() => {
|
|
function isOdd(n: number) {
|
|
return n % 2 === 1;
|
|
}
|
|
|
|
R.reject(isOdd, [1, 2, 3, 4]); // => [2, 4]
|
|
R.reject(isOdd)([1, 2, 3, 4]); // => [2, 4]
|
|
};
|
|
|
|
() => {
|
|
function lastTwo(val: number, idx: number, list: number[]) {
|
|
return list.length - idx <= 2;
|
|
}
|
|
|
|
const rejectIndexed = R.addIndex(R.reject);
|
|
rejectIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); // => [8, 6, 7, 5, 3]
|
|
rejectIndexed(lastTwo)([8, 6, 7, 5, 3, 0, 9]); // => [8, 6, 7, 5, 3]
|
|
};
|
|
|
|
() => {
|
|
R.remove(2, 3, [1, 2, 3, 4, 5, 6, 7, 8]); // => [1,2,6,7,8]
|
|
R.remove(2, 3)([1, 2, 3, 4, 5, 6, 7, 8]); // => [1,2,6,7,8]
|
|
R.remove(2)(3, [1, 2, 3, 4, 5, 6, 7, 8]); // => [1,2,6,7,8]
|
|
};
|
|
|
|
() => {
|
|
R.repeat("hi", 5); // => ['hi', 'hi', 'hi', 'hi', 'hi']
|
|
const obj = {};
|
|
const repeatedObjs = R.repeat(obj, 5); // => [{}, {}, {}, {}, {}]
|
|
repeatedObjs[0] === repeatedObjs[1]; // => true
|
|
};
|
|
|
|
() => {
|
|
R.reverse([1, 2, 3]); // => [3, 2, 1]
|
|
R.reverse([1, 2]); // => [2, 1]
|
|
R.reverse([1]); // => [1]
|
|
R.reverse([]); // => []
|
|
};
|
|
|
|
() => {
|
|
R.reverse('abc'); // => 'cba'
|
|
R.reverse('ab'); // => 'ba'
|
|
R.reverse('a'); // => 'a'
|
|
R.reverse(''); // => ''
|
|
};
|
|
|
|
() => {
|
|
const numbers = [1, 2, 3, 4];
|
|
R.scan(R.multiply, 1, numbers); // => [1, 1, 2, 6, 24]
|
|
R.scan(R.multiply, 1)(numbers); // => [1, 1, 2, 6, 24]
|
|
R.scan(R.multiply)(1, numbers); // => [1, 1, 2, 6, 24]
|
|
};
|
|
|
|
() => {
|
|
const xs = R.range(0, 10);
|
|
R.slice(2, 5, xs); // => [2, 3, 4]
|
|
R.slice(2, 5)(xs); // => [2, 3, 4]
|
|
R.slice(2)(5, xs); // => [2, 3, 4]
|
|
|
|
const str = "Hello World";
|
|
R.slice(2, 5, str); // => 'llo'
|
|
R.slice(2, 5)(str); // => 'llo'
|
|
R.slice(2)(5, str); // => 'llo'
|
|
};
|
|
|
|
() => {
|
|
function diff(a: number, b: number) {
|
|
return a - b;
|
|
}
|
|
|
|
R.sort(diff, [4, 2, 7, 5]); // => [2, 4, 5, 7]
|
|
R.sort(diff)([4, 2, 7, 5]); // => [2, 4, 5, 7]
|
|
};
|
|
|
|
() => {
|
|
const f = R.cond<number, string>([
|
|
[x => x === 0, () => "a"],
|
|
[() => true, () => "b"],
|
|
]);
|
|
f(0); // $ExpectType string
|
|
f(""); // $ExpectError
|
|
f(1, 2); // $ExpectType string
|
|
|
|
const g = R.cond([
|
|
[(a, b) => a === b, () => "a"],
|
|
[() => true, () => "b"],
|
|
]);
|
|
g(0);
|
|
g("");
|
|
g(1, "");
|
|
};
|
|
|
|
() => {
|
|
R.tail(["fi", "fo", "fum"]); // => ['fo', 'fum']
|
|
R.tail([1, 2, 3]); // => [2, 3]
|
|
R.tail("abc"); // => 'bc'
|
|
R.tail(""); // => ''
|
|
};
|
|
|
|
() => {
|
|
R.take(3, [1, 2, 3, 4, 5]); // => [1,2,3]
|
|
|
|
const members = ["Paul Desmond", "Bob Bates", "Joe Dodge", "Ron Crotty", "Lloyd Davis", "Joe Morello", "Norman Bates",
|
|
"Eugene Wright", "Gerry Mulligan", "Jack Six", "Alan Dawson", "Darius Brubeck", "Chris Brubeck",
|
|
"Dan Brubeck", "Bobby Militello", "Michael Moore", "Randy Jones"];
|
|
const takeFive = R.take(5);
|
|
takeFive(members); // => ["Paul Desmond","Bob Bates","Joe Dodge","Ron Crotty","Lloyd Davis"]
|
|
};
|
|
|
|
() => {
|
|
R.take(3, "Example"); // => "Exa"
|
|
|
|
const takeThree = R.take(3);
|
|
takeThree("Example"); // => "Exa"
|
|
};
|
|
|
|
() => {
|
|
const a: string[] = R.takeLast(1, ["foo", "bar", "baz"]); // => ['baz']
|
|
const b: string[] = R.takeLast(2)(["foo", "bar", "baz"]); // => ['bar', 'baz']
|
|
const c: string = R.takeLast(3, "ramda"); // => 'mda'
|
|
const d: string = R.takeLast(3)("ramda"); // => 'mda'
|
|
};
|
|
|
|
() => {
|
|
const isNotOne = (x: number) => x !== 1;
|
|
const a: number[] = R.takeLastWhile(isNotOne, [1, 2, 3, 4]); // => [2, 3, 4]
|
|
const b: number[] = R.takeLastWhile(isNotOne)([1, 2, 3, 4]); // => [2, 3, 4]
|
|
};
|
|
|
|
() => {
|
|
function isNotFour(x: number) {
|
|
return !(x === 4);
|
|
}
|
|
|
|
R.takeWhile(isNotFour, [1, 2, 3, 4]); // => [1, 2, 3]
|
|
R.takeWhile(isNotFour)([1, 2, 3, 4]); // => [1, 2, 3]
|
|
};
|
|
|
|
() => {
|
|
const sayX = (x: number) => console.log("x is " + x);
|
|
const a: number = R.tap(sayX, 100); // => 100
|
|
};
|
|
|
|
() => {
|
|
const a: boolean = R.test(/^x/, "xyz"); // => true
|
|
const b: boolean = R.test(/^y/)("xyz"); // => false
|
|
};
|
|
|
|
() => {
|
|
interface Person { id: number; firstName: string; lastName: string; }
|
|
const makeQuery = (email: string) => ({ query: { email }});
|
|
const fetchMember = (query: any) => Promise.resolve({ id: 1, firstName: 'Jon', lastName: 'Snow' });
|
|
const getTitleAsync = (person: Person) => person.firstName === 'Jon' && person.lastName === 'Snow' ? Promise.resolve('King in the North') : Promise.reject('Unknown');
|
|
|
|
const getMemberName: (email: string) => Promise<{ firstName: string, lastName: string }> = R.pipe(
|
|
makeQuery,
|
|
fetchMember,
|
|
R.then(R.pick(['firstName', 'lastName'])),
|
|
);
|
|
|
|
const getMemberTitle: (email: string) => Promise<string> = R.pipe(
|
|
makeQuery,
|
|
fetchMember,
|
|
R.then(getTitleAsync),
|
|
);
|
|
};
|
|
|
|
() => {
|
|
const x: number = R.thunkify(R.identity)(42)();
|
|
const y: number = R.thunkify((a: number, b: number) => a + b)(25, 17)();
|
|
const z: number = R.thunkify((a: number, b: number) => a + b)(25)(17)();
|
|
};
|
|
|
|
() => {
|
|
const a1 = R.times(R.identity, 5); // => [0, 1, 2, 3, 4]
|
|
const a2 = R.times(R.identity)(5); // => [0, 1, 2, 3, 4]
|
|
};
|
|
|
|
() => {
|
|
class Point {
|
|
constructor(public x: number, public y: number) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
|
|
toStringn() {
|
|
return `new Point(${this.x}, ${this.y})`;
|
|
}
|
|
}
|
|
R.toString(new Point(1, 2)); // => 'new Point(1, 2)'
|
|
|
|
R.toString(42); // => '42'
|
|
R.toString("abc"); // => '"abc"'
|
|
R.toString([1, 2, 3]); // => '[1, 2, 3]'
|
|
R.toString({foo: 1, bar: 2, baz: 3}); // => '{"bar": 2, "baz": 3, "foo": 1}'
|
|
R.toString(new Date("2001-02-03T04:05:06Z")); // => 'new Date("2001-02-03T04:05:06.000Z")'
|
|
};
|
|
|
|
() => {
|
|
const numbers = [1, 2, 3, 4];
|
|
const transducer = R.compose(R.map(R.add(1)), R.take(2));
|
|
const fn = R.flip<number, number[], number[]>(R.append);
|
|
R.transduce(transducer, fn, [], numbers); // => [2, 3]
|
|
R.transduce(transducer, fn, [])(numbers); // => [2, 3]
|
|
R.transduce(transducer, fn)([], numbers); // => [2, 3]
|
|
R.transduce<number, number>(transducer)(fn, [], numbers); // => [2, 3]
|
|
};
|
|
|
|
() => {
|
|
const a: Array<Array<number | string>> = R.transpose<number | string>([[1, "a"], [2, "b"], [3, "c"]]); // => [[1, 2, 3], ['a', 'b', 'c']]
|
|
const b: Array<Array<number | string>> = R.transpose<number | string>([[1, 2, 3], ["a", "b", "c"]]); // => [[1, 'a'], [2, 'b'], [3, 'c']]
|
|
const c: number[][] = R.transpose([[10, 11], [20], [], [30, 31, 32]]); // => [[10, 20, 30], [11, 31], [32]]
|
|
};
|
|
|
|
() => {
|
|
const of = Array.of;
|
|
const fn = (x: number) => Array.of(x + 1);
|
|
const list = [1, 2, 3];
|
|
R.traverse(of, fn, list);
|
|
R.traverse(of, fn)(list);
|
|
R.traverse<number, number>(of)(fn, list);
|
|
};
|
|
|
|
() => {
|
|
const x = R.prop("x");
|
|
const a: boolean = R.tryCatch<boolean>(R.prop("x"), R.F)({x: true}); // => true
|
|
const a1: boolean = R.tryCatch(R.prop<"x", true>("x"), R.F)({x: true}); // => true
|
|
const b: boolean = R.tryCatch<boolean>(R.prop("x"), R.F)(null); // => false
|
|
const c: boolean = R.tryCatch<boolean>(R.and, R.F)(true, true); // => true
|
|
};
|
|
|
|
() => {
|
|
R.uniq([1, 1, 2, 1]); // => [1, 2]
|
|
R.uniq([{}, {}]); // => [{}, {}]
|
|
R.uniq([1, "1"]); // => [1, '1']
|
|
};
|
|
|
|
() => {
|
|
function strEq(a: any, b: any) {
|
|
return String(a) === String(b);
|
|
}
|
|
|
|
R.uniqWith(strEq, [1, "1", 2, 1]); // => [1, 2]
|
|
R.uniqWith(strEq)([1, "1", 2, 1]); // => [1, 2]
|
|
R.uniqWith(strEq)([{}, {}]); // => [{}]
|
|
R.uniqWith(strEq)([1, "1", 1]); // => [1]
|
|
R.uniqWith(strEq)(["1", 1, 1]); // => ['1']
|
|
};
|
|
|
|
() => {
|
|
R.equals(R.unnest([1, [2], [[3]]]), [1, 2, [3]]); // => true
|
|
R.equals(R.unnest<number>([[1, 2], [3, 4], [5, 6]]), [1, 2, 3, 4, 5, 6]); // => true
|
|
};
|
|
|
|
() => {
|
|
R.xprod([1, 2], ["a", "b"]); // => [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
|
|
R.xprod([1, 2])(["a", "b"]); // => [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
|
|
};
|
|
|
|
() => {
|
|
R.zip([1, 2, 3], ["a", "b", "c"]); // => [[1, 'a'], [2, 'b'], [3, 'c']]
|
|
R.zip([1, 2, 3])(["a", "b", "c"]); // => [[1, 'a'], [2, 'b'], [3, 'c']]
|
|
};
|
|
|
|
() => {
|
|
R.zipObj(["a", "b", "c"], [1, 2, 3]); // => {a: 1, b: 2, c: 3}
|
|
R.zipObj(["a", "b", "c"])([1, 2, 3]); // => {a: 1, b: 2, c: 3}
|
|
};
|
|
|
|
() => {
|
|
function f(x: number, y: string) {
|
|
// ...
|
|
}
|
|
|
|
R.zipWith(f, [1, 2, 3], ["a", "b", "c"]); // => [f(1, 'a'), f(2, 'b'), f(3, 'c')]
|
|
R.zipWith(f)([1, 2, 3], ["a", "b", "c"]); // => [f(1, 'a'), f(2, 'b'), f(3, 'c')]
|
|
R.zipWith(f, [1, 2, 3])(["a", "b", "c"]); // => [f(1, 'a'), f(2, 'b'), f(3, 'c')]
|
|
};
|
|
|
|
/*****************************************************************
|
|
* Object category
|
|
*/
|
|
() => {
|
|
interface ABC { a: number; b: number; c: number; }
|
|
const a: ABC = R.assoc("c", 3, {a: 1, b: 2}); // => {a: 1, b: 2, c: 3}
|
|
const b: ABC = R.assoc("c")(3, {a: 1, b: 2}); // => {a: 1, b: 2, c: 3}
|
|
const c: ABC = R.assoc("c", 3)({a: 1, b: 2}); // => {a: 1, b: 2, c: 3}
|
|
const d: ABC = R.assoc(R.__, 3, {a: 1, b: 2})("c"); // => {a: 1, b: 2, c: 3}
|
|
const e: ABC = R.assoc("c", R.__, {a: 1, b: 2})(3); // => {a: 1, b: 2, c: 3}
|
|
};
|
|
|
|
() => {
|
|
type ABC = Record<string, string>;
|
|
const b: ABC = R.compose(R.assoc, R.toString)(3)("c", {1: "a", 2: "b"}); // => {1: "a", 2: "b", 3: "c"}
|
|
};
|
|
|
|
() => {
|
|
const a1 = R.dissoc<{ a: number, c: number }>("b", {a: 1, b: 2, c: 3}); // => {a: 1, c: 3}
|
|
const a2 = R.dissoc("b", {a: 1, b: 2, c: 3}); // => {a: 1, c: 3}
|
|
const a4 = R.dissoc("b")<{ a: number, c: number }>({a: 1, b: 2, c: 3}); // => {a: 1, c: 3}
|
|
};
|
|
|
|
() => {
|
|
const testPath = ["x", 0, "y"];
|
|
const testObj = {x: [{y: 2, z: 3}, {y: 4, z: 5}]};
|
|
|
|
R.assocPath(R.__, 42, testObj)(testPath); // => {x: [{y: 42, z: 3}, {y: 4, z: 5}]}
|
|
R.assocPath(testPath, R.__, testObj)(42); // => {x: [{y: 42, z: 3}, {y: 4, z: 5}]}
|
|
R.assocPath(testPath, 42, testObj); // => {x: [{y: 42, z: 3}, {y: 4, z: 5}]}
|
|
R.assocPath(testPath, 42)(testObj); // => {x: [{y: 42, z: 3}, {y: 4, z: 5}]}
|
|
R.assocPath(testPath)(42)(testObj); // => {x: [{y: 42, z: 3}, {y: 4, z: 5}]}
|
|
R.assocPath(testPath)(42, testObj); // => {x: [{y: 42, z: 3}, {y: 4, z: 5}]}
|
|
};
|
|
|
|
() => {
|
|
const a1 = R.dissocPath(["a", "b", "c"], {a: {b: {c: 42}}}); // => {a: {b: {}}}
|
|
// optionally specify return type
|
|
const a2 = R.dissocPath<{ a: { b: number } }>(["a", "b", "c"], {a: {b: {c: 42}}}); // => {a: {b: {}}}
|
|
const a3 = R.dissocPath(["a", "b", "c"])({a: {b: {c: 42}}}); // => {a: {b: {}}}
|
|
|
|
const testPath = ["x", 0, "y"];
|
|
const testObj = {x: [{y: 2, z: 3}, {y: 4, z: 5}]};
|
|
|
|
R.dissocPath(testPath, testObj); // => {x: [{z: 3}, {y: 4, z: 5}]}
|
|
R.dissocPath(testPath)(testObj); // => {x: [{z: 3}, {y: 4, z: 5}]}
|
|
};
|
|
|
|
() => {
|
|
const obj1 = [{}, {}, {}];
|
|
const obj2 = [{a: 1}, {a: 2}, {a: 3}];
|
|
const a1: any[] = R.clone(obj1);
|
|
const a2: Array<{ a: number }> = R.clone(obj2);
|
|
const a3: any = R.clone({});
|
|
const a4: number = R.clone(10);
|
|
const a5: string = R.clone("foo");
|
|
const a6: number = R.clone(Date.now());
|
|
};
|
|
|
|
() => {
|
|
const o1 = {a: 1, b: 2, c: 3, d: 4};
|
|
const o2 = {a: 10, b: 20, c: 3, d: 40};
|
|
const a1 = R.eqProps("a", o1, o2); // => false
|
|
const a2 = R.eqProps("c", o1, o2); // => true
|
|
const a3: <T extends { c: any }, U extends { c: any }>(obj1: T, obj2: U) => boolean = R.eqProps("c");
|
|
const a4: <U>(obj2: U) => boolean = R.eqProps("c", o1);
|
|
};
|
|
|
|
() => {
|
|
// No type transformation
|
|
|
|
const a1 = R.evolve({ elapsed: R.add(1), remaining: R.add(-1) }, { name: "Tomato", elapsed: 100, remaining: 1400 });
|
|
|
|
const a1Test: { elapsed: number, remaining: number, name: string } = a1;
|
|
|
|
const a2 = R.evolve({ elapsed: R.add(1), remaining: R.add(-1) })({ name: "Tomato", elapsed: 100, remaining: 1400 });
|
|
|
|
const a2Test: { elapsed: number, remaining: number, name: string } = a2;
|
|
|
|
// Object doesn't have all evolver keys
|
|
|
|
const a3 = R.evolve({ age: R.add(1), name: R.trim }, { name: "Potato", elapsed: 100 });
|
|
|
|
const a3Test: { name: string, elapsed: number } = a3;
|
|
|
|
// Flat transformation
|
|
|
|
const ex0 = R.evolve({ a: parseInt }, { a: '10', b: 1 });
|
|
|
|
const ex0Test: { a: number, b: number } = ex0;
|
|
|
|
// Nested transformation:
|
|
|
|
const ex1 = R.evolve(
|
|
{ a: { b: R.toString, d: { e: R.toString } } },
|
|
{ a: { b: 1, c: null, d: { e: 2 } } },
|
|
);
|
|
|
|
const ex1Test: { a: { b: string, c: null, d: { e: string } } } = ex1;
|
|
|
|
// Mapping a nested object with a single function
|
|
|
|
const ex2 = R.evolve(
|
|
{ a: (obj: { foo: string }) => ({ bar: 1, baz: 2 }) },
|
|
{ a: { foo: 'a', skipped: 3 }, b: null },
|
|
);
|
|
|
|
const ex2Test: { a: { bar: number, baz: number }, b: null } = ex2;
|
|
|
|
// Nested curried:
|
|
|
|
const ex3 = R.evolve(
|
|
{ a: { b: R.toString, d: { e: R.toString } } },
|
|
)(
|
|
{ a: { b: 1, c: null, d: { e: 2 } } }
|
|
);
|
|
|
|
const ex3Test: { a: { b: string, c: null, d: { e: string } } } = ex3;
|
|
};
|
|
|
|
() => {
|
|
const hasName = R.has("name");
|
|
const a1: boolean = hasName({name: "alice"}); // => true
|
|
const a2: boolean = hasName({name: "bob"}); // => true
|
|
const a3: boolean = hasName({}); // => false
|
|
|
|
const point = {x: 0, y: 0};
|
|
const pointHas = R.flip(R.has)(point);
|
|
const b1: boolean = pointHas("x"); // => true
|
|
const b2: boolean = pointHas("y"); // => true
|
|
const b3: boolean = pointHas("z"); // => false
|
|
};
|
|
|
|
class Rectangle {
|
|
constructor(public width: number, public height: number) {
|
|
this.width = width;
|
|
this.height = height;
|
|
}
|
|
|
|
area(): number {
|
|
return this.width * this.height;
|
|
}
|
|
}
|
|
|
|
() => {
|
|
const square = new Rectangle(2, 2);
|
|
R.hasIn("width", square); // => true
|
|
R.hasIn("area", square); // => true
|
|
R.flip(R.hasIn)(square)("area"); // => true
|
|
};
|
|
|
|
() => {
|
|
R.hasPath(['a', 'b'], {a: {b: 2}}); // true
|
|
R.hasPath(['a', 'b'], {a: {b: undefined}}); // => true
|
|
R.hasPath(['a', 'b'], {a: {c: 2}}); // => false
|
|
R.hasPath(['a', 'b'], {}); // => false
|
|
|
|
const hasPathCurried = R.hasPath(['a', 'b']);
|
|
hasPathCurried({a: {b: 2}}); // true
|
|
};
|
|
|
|
() => {
|
|
const raceResultsByFirstName = {
|
|
first : "alice",
|
|
second: "jake",
|
|
third : "alice",
|
|
};
|
|
R.invert(raceResultsByFirstName);
|
|
// => { 'alice': ['first', 'third'], 'jake':['second'] }
|
|
};
|
|
|
|
() => {
|
|
const raceResults0 = {
|
|
first : "alice",
|
|
second: "jake"
|
|
};
|
|
R.invertObj(raceResults0);
|
|
// => { 'alice': 'first', 'jake':'second' }
|
|
|
|
// Alternatively:
|
|
const raceResults1 = ["alice", "jake"];
|
|
R.invertObj(raceResults1);
|
|
// => { 'alice': '0', 'jake':'1' }
|
|
};
|
|
|
|
() => {
|
|
const objKeys = R.keys({a: 1, b: 2, c: 3}); // => ['a', 'b', 'c']
|
|
const numberKeys = R.keys(1);
|
|
const arrayKeys = R.keys([]);
|
|
const stringKeys = R.keys('foo');
|
|
};
|
|
|
|
() => {
|
|
const f = new F();
|
|
R.keysIn(f); // => ['x', 'y']
|
|
};
|
|
|
|
() => {
|
|
interface Person { firstName: string; lastName: string; }
|
|
const failedFetch = (id: string): Promise<Person> => Promise.reject('bad ID');
|
|
const useDefault = (): Person => ({ firstName: 'Bob', lastName: 'Loblaw' });
|
|
const loadAlternative = (): Promise<Person> => Promise.resolve({ firstName: 'Saul', lastName: 'Goodman' });
|
|
|
|
const recoverFromFailure: (id: string) => Promise<{ firstName: string; lastName: string; }> = R.pipe(
|
|
failedFetch,
|
|
R.otherwise(useDefault),
|
|
R.then(R.pick(['firstName', 'lastName'])),
|
|
);
|
|
|
|
const recoverFromFailureByAlternative: (id: string) => Promise<Person> = R.pipe(
|
|
failedFetch,
|
|
R.otherwise(useDefault),
|
|
R.then(loadAlternative),
|
|
);
|
|
};
|
|
|
|
() => {
|
|
const xLens = R.lens(R.prop("x"), R.assoc("x"));
|
|
R.view(xLens, {x: 1, y: 2}); // => 1
|
|
R.view(xLens)({x: 1, y: 2}); // => 1
|
|
R.set(xLens, 4, {x: 1, y: 2}); // => {x: 4, y: 2}
|
|
R.set(xLens)(4, {x: 1, y: 2}); // => {x: 4, y: 2}
|
|
R.set(xLens, 4)({x: 1, y: 2}); // => {x: 4, y: 2}
|
|
R.over(xLens, R.negate, {x: 1, y: 2}); // => {x: -1, y: 2}
|
|
R.over(xLens, R.negate)({x: 1, y: 2}); // => {x: -1, y: 2}
|
|
R.over(xLens)(R.negate, {x: 1, y: 2}); // => {x: -1, y: 2}
|
|
};
|
|
|
|
() => {
|
|
const headLens = R.lensIndex(0);
|
|
R.view(headLens, ["a", "b", "c"]); // => 'a'
|
|
R.set(headLens, "x", ["a", "b", "c"]); // => ['x', 'b', 'c']
|
|
R.over(headLens, R.toUpper, ["a", "b", "c"]); // => ['A', 'b', 'c']
|
|
};
|
|
|
|
() => {
|
|
const xLens = R.lensProp("x");
|
|
R.view(xLens, {x: 1, y: 2}); // => 1
|
|
R.set(xLens, 4, {x: 1, y: 2}); // => {x: 4, y: 2}
|
|
R.over(xLens, R.negate, {x: 1, y: 2}); // => {x: -1, y: 2}
|
|
};
|
|
|
|
() => {
|
|
const xyLens = R.lensPath(["x", 0, "y"]);
|
|
const testObj = {x: [{y: 2, z: 3}, {y: 4, z: 5}]};
|
|
|
|
R.view(xyLens, testObj); // => 2
|
|
R.set(xyLens, 4, testObj); // => {x: [{y: 4, z: 3}, {y: 4, z: 5}]}
|
|
R.over(xyLens, R.negate, testObj); // => {x: [{y: -2, z: 3}, {y: 4, z: 5}]}
|
|
};
|
|
|
|
() => {
|
|
R.keys({a: 1, b: 2, c: 3}); // => ['a', 'b', 'c']
|
|
};
|
|
|
|
() => {
|
|
const f = new F();
|
|
R.keysIn(f); // => ['x', 'y']
|
|
};
|
|
|
|
() => {
|
|
const headLens = R.lens(
|
|
function get(arr: number[]) {
|
|
return arr[0];
|
|
},
|
|
function set(val: number, arr: number[]) {
|
|
return [val].concat(arr.slice(1));
|
|
}
|
|
);
|
|
headLens([10, 20, 30, 40]); // => 10
|
|
headLens.set("mu", [10, 20, 30, 40]); // => ['mu', 20, 30, 40]
|
|
|
|
const phraseLens = R.lens(
|
|
function get(obj: any) {
|
|
return obj.phrase;
|
|
},
|
|
function set(val: string, obj: any) {
|
|
const out = R.clone(obj);
|
|
out.phrase = val;
|
|
return out;
|
|
}
|
|
);
|
|
const obj1 = {phrase: "Absolute filth . . . and I LOVED it!"};
|
|
const obj2 = {phrase: "What's all this, then?"};
|
|
phraseLens(obj1); // => 'Absolute filth . . . and I LOVED it!'
|
|
phraseLens(obj2); // => "What's all this, then?"
|
|
phraseLens.set("Ooh Betty", obj1); // => { phrase: 'Ooh Betty'}
|
|
};
|
|
|
|
() => {
|
|
const phraseLens = R.lensProp("phrase");
|
|
const obj1 = {phrase: "Absolute filth . . . and I LOVED it!"};
|
|
const obj2 = {phrase: "What's all this, then?"};
|
|
phraseLens(obj1); // => 'Absolute filth . . . and I LOVED it!'
|
|
phraseLens(obj2); // => "What's all this, then?"
|
|
phraseLens.set("Ooh Betty", obj1); // => { phrase: 'Ooh Betty'}
|
|
};
|
|
|
|
() => {
|
|
R.merge({name: "fred", age: 10}, {age: 40});
|
|
// => { 'name': 'fred', 'age': 40 }
|
|
|
|
const resetToDefault = R.flip(R.merge)({x: 0});
|
|
resetToDefault({x: 5, y: 2}); // => {x: 0, y: 2}
|
|
};
|
|
|
|
() => {
|
|
interface FBB { foo?: number; bar?: number; baz?: number; }
|
|
const a = R.mergeAll([{foo: 1}, {bar: 2}, {baz: 3}]); // => {foo:1,bar:2,baz:3}
|
|
const b = R.mergeAll([{foo: 1}, {foo: 2}, {bar: 2}]); // => {foo:2,bar:2}
|
|
const c = R.mergeAll<FBB>([{foo: 1}, {bar: 2}, {baz: 3}]); // => {foo:1,bar:2,baz:3}
|
|
const d = R.mergeAll<FBB>([{foo: 1}, {foo: 2}, {bar: 2}]); // => {foo:2,bar:2}
|
|
};
|
|
|
|
() => {
|
|
const a = R.mergeDeepLeft({foo: {bar: 1}}, {foo: {bar: 2}}); // => {foo: {bar: 1}}
|
|
};
|
|
|
|
() => {
|
|
const a = R.mergeDeepRight({foo: {bar: 1}}, {foo: {bar: 2}}); // => {foor: bar: 2}}
|
|
};
|
|
|
|
() => {
|
|
const a = R.mergeDeepWith(
|
|
(a: number[], b: number[]) => a.concat(b),
|
|
{foo: {bar: [1, 2]}},
|
|
{foo: {bar: [3, 4]}},
|
|
); // => {foo: {bar: [1,2,3,4]}}
|
|
};
|
|
|
|
() => {
|
|
const a = R.mergeDeepWithKey(
|
|
(k: string, a: number[], b: number[]) => k === 'bar' ? a.concat(b) : a,
|
|
{foo: {bar: [1, 2], userIds: [42]}},
|
|
{foo: {bar: [3, 4], userIds: [34]}}
|
|
); // => { foo: { bar: [ 1, 2, 3, 4 ], userIds: [42] } }
|
|
};
|
|
|
|
() => {
|
|
R.mergeLeft({foo: {bar: 1}}, {foo: {bar: 2}}); // => {foo: {bar: 1}}
|
|
const curry1 = R.mergeLeft({foo: {bar: 1}});
|
|
curry1({foo: {bar: 2}}); // => {foo: {bar: 1}}
|
|
};
|
|
|
|
() => {
|
|
R.mergeRight({ name: 'fred', age: 10 }, { age: 40 });
|
|
// => { 'name': 'fred', 'age': 40 }
|
|
|
|
const withDefaults = R.mergeRight({x: 0, y: 0});
|
|
withDefaults({y: 2}); // => {x: 0, y: 2}
|
|
};
|
|
|
|
() => {
|
|
const a = R.mergeWith(R.concat,
|
|
{a: true, values: [10, 20]},
|
|
{b: true, values: [15, 35]});
|
|
// => { a: true, b: true, values: [10, 20, 15, 35] }
|
|
};
|
|
|
|
() => {
|
|
const concatValues = (k: string, l: string, r: string) => k === "values" ? R.concat(l, r) : r;
|
|
R.mergeWithKey(concatValues,
|
|
{a: true, thing: "foo", values: [10, 20]},
|
|
{b: true, thing: "bar", values: [15, 35]});
|
|
const merge = R.mergeWithKey(concatValues);
|
|
merge({a: true, thing: "foo", values: [10, 20]}, {b: true, thing: "bar", values: [15, 35]});
|
|
};
|
|
|
|
() => {
|
|
const orValue = "N/A";
|
|
const testPath = ["x", 0, "y"];
|
|
const testObj = {x: [{y: 2, z: 3}, {y: 4, z: 5}]};
|
|
|
|
R.pathOr(orValue, testPath, testObj); // => 2
|
|
R.pathOr(orValue, testPath)(testObj); // => 2
|
|
R.pathOr(orValue)(testPath)(testObj); // => 2
|
|
R.pathOr(orValue)(testPath, testObj); // => 2
|
|
R.pathOr(orValue, testPath, {c: {b: 2}}); // => "N/A"
|
|
};
|
|
|
|
() => {
|
|
const a: boolean = R.pathSatisfies((x: number) => x > 0, ["x"], {x: 1, y: 2}); // => true
|
|
const b: boolean = R.pathSatisfies((x: number) => x > 0, ["x"])({x: 1, y: 2}); // => true
|
|
const c: boolean = R.pathSatisfies((x: number) => x > 0)(["x"])({x: 1, y: 2}); // => true
|
|
};
|
|
|
|
() => {
|
|
function isPositive(n: number) {
|
|
return n > 0;
|
|
}
|
|
|
|
const a1 = R.pickBy(isPositive, {a: 1, b: 2, c: -1, d: 0, e: 5}); // => {a: 1, b: 2, e: 5}
|
|
function containsBackground(val: any) {
|
|
return val.bgcolor;
|
|
}
|
|
|
|
const colors = {1: {color: "read"}, 2: {color: "black", bgcolor: "yellow"}};
|
|
R.pickBy(containsBackground, colors); // => {2: {color: 'black', bgcolor: 'yellow'}}
|
|
|
|
function isUpperCase(val: number, key: string) {
|
|
return key.toUpperCase() === key;
|
|
}
|
|
|
|
R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); // => {A: 3, B: 4}
|
|
};
|
|
|
|
() => {
|
|
const a1 = R.pick(["a", "d"], {a: 1, b: 2, c: 3, d: 4}); // => {a: 1, d: 4}
|
|
const a2 = R.pick(["a", "e", "f"], {a: 1, b: 2, c: 3, d: 4}); // => {a: 1}
|
|
const a3 = R.pick(["a", "e", "f"])({a: 1, b: 2, c: 3, d: 4}); // => {a: 1}
|
|
const a4 = R.pick(["a", "e", "f"], [1, 2, 3, 4]); // => {a: 1}
|
|
};
|
|
|
|
() => {
|
|
const matchPhrases = (xs: string[]) => R.objOf("must",
|
|
R.map(
|
|
(x: string) => R.objOf("match_phrase", x),
|
|
xs
|
|
)
|
|
);
|
|
|
|
const out: { must: Array<{ match_phrase: string }> } =
|
|
matchPhrases(["foo", "bar", "baz"]);
|
|
};
|
|
|
|
() => {
|
|
R.omit(["a", "d"], {a: 1, b: 2, c: 3, d: 4}); // => {b: 2, c: 3}
|
|
R.omit(["a", "d"])({a: 1, b: 2, c: 3, d: 4}); // => {b: 2, c: 3}
|
|
};
|
|
|
|
() => {
|
|
R.fromPairs([["a", 1], ["b", 2], ["c", 3]]); // => {a: 1, b: 2, c: 3}
|
|
};
|
|
|
|
() => {
|
|
R.pair("foo", "bar"); // => ['foo', 'bar']
|
|
const p = R.pair("foo", 1); // => ['foo', 'bar']
|
|
const x: string = p[0];
|
|
const y: number = p[1];
|
|
};
|
|
|
|
() => {
|
|
const headLens = R.lensIndex(0);
|
|
R.over(headLens, R.toUpper, ["foo", "bar", "baz"]); // => ['FOO', 'bar', 'baz']
|
|
};
|
|
|
|
() => {
|
|
R.pickAll(["a", "d"], {a: 1, b: 2, c: 3, d: 4}); // => {a: 1, d: 4}
|
|
R.pickAll(["a", "d"])({a: 1, b: 2, c: 3, d: 4}); // => {a: 1, d: 4}
|
|
R.pickAll(["a", "e", "f"], {a: 1, b: 2, c: 3, d: 4}); // => {a: 1, e: undefined, f: undefined}
|
|
R.pickAll(["a", "e", "f"])({a: 1, b: 2, c: 3, d: 4}); // => {a: 1, e: undefined, f: undefined}
|
|
};
|
|
|
|
() => {
|
|
function isUpperCase(val: number, key: string) {
|
|
return key.toUpperCase() === key;
|
|
}
|
|
|
|
R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); // => {A: 3, B: 4}
|
|
};
|
|
|
|
() => {
|
|
const abby = {name: "Abby", age: 7, hair: "blond", grade: 2};
|
|
const fred = {name: "Fred", age: 12, hair: "brown", grade: 7};
|
|
const kids = [abby, fred];
|
|
R.project(["name", "grade"], kids); // => [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}]
|
|
R.project(["name", "grade"])(kids); // => [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}]
|
|
};
|
|
|
|
() => {
|
|
const x: number = R.prop("x", {x: 100}); // => 100
|
|
const obj = {
|
|
str: 'string',
|
|
num: 5,
|
|
};
|
|
|
|
const strVal: string = R.prop('str', obj); // => 'string'
|
|
const numVal: number = R.prop('num', obj); // => 5
|
|
|
|
const strValPl: string = R.prop(R.__, obj)('str'); // => 'string'
|
|
|
|
const strValCur: string = R.prop('str')(obj); // => 'string'
|
|
const numValCur: number = R.prop('num')(obj); // => 5
|
|
};
|
|
|
|
() => {
|
|
const alice = {
|
|
name: "ALICE",
|
|
age : 101
|
|
};
|
|
const favorite = R.prop("favoriteLibrary");
|
|
const favoriteWithDefault = R.propOr("Ramda", "favoriteLibrary");
|
|
|
|
const s2 = favoriteWithDefault(alice); // => 'Ramda'
|
|
R.propOr('Ramda', R.__, alice)('name'); // => 'ALICE'
|
|
R.propOr(R.__, 'foo', alice)('default'); // => 'default'
|
|
};
|
|
|
|
() => {
|
|
const a: boolean = R.propSatisfies((x: number) => x > 0, "x", {x: 1, y: 2}); // => true
|
|
const b: boolean = R.propSatisfies((x: number) => x > 0, "x")({x: 1, y: 2}); // => true
|
|
const c: boolean = R.propSatisfies((x: number) => x > 0)("x")({x: 1, y: 2}); // => true
|
|
};
|
|
|
|
() => {
|
|
R.props(["x", "y"], {x: 1, y: 2}); // => [1, 2]
|
|
|
|
const fullName = R.compose(R.join(" "), R.props(["first", "last"]));
|
|
fullName({last: "Bullet-Tooth", age: 33, first: "Tony"}); // => 'Tony Bullet-Tooth'
|
|
};
|
|
|
|
() => {
|
|
const a = R.toPairs<number>({a: 1, b: 2, c: 3}); // => [['a', 1], ['b', 2], ['c', 3]]
|
|
const b = R.toPairs({1: 'a'}); // => [['1', 'something']]
|
|
};
|
|
|
|
() => {
|
|
const f = new F();
|
|
const a1 = R.toPairsIn(f); // => [['x','X'], ['y','Y']]
|
|
const a2 = R.toPairsIn<string>(f); // => [['x','X'], ['y','Y']]
|
|
};
|
|
|
|
() => {
|
|
interface A {
|
|
a: string;
|
|
b: string;
|
|
}
|
|
const a1: A = { a: 'something', b: 'else' };
|
|
const v1 = R.values(a1);
|
|
|
|
const a = R.values({a: 1, b: 2, c: 3}); // => [1, 2, 3] (number[])
|
|
const addition = a[0] + a[1];
|
|
|
|
const b = R.values({a: 1, b: 'something'}); // b = (string|number)[]
|
|
const c = R.values({1: 3});
|
|
// const d = R.values('something');
|
|
};
|
|
|
|
() => {
|
|
const f = new F();
|
|
const a = R.valuesIn(f); // => ['X', 'Y']
|
|
};
|
|
|
|
() => {
|
|
const spec = {x: 2};
|
|
const x1: boolean = R.where(spec, {w: 10, x: 2, y: 300}); // => true
|
|
const x2: boolean = R.where(spec, {x: 1, y: "moo", z: true}); // => false
|
|
const x3: boolean = R.where(spec)({w: 10, x: 2, y: 300}); // => true
|
|
const x4: boolean = R.where(spec)({x: 1, y: "moo", z: true}); // => false
|
|
|
|
// There's no way to represent the below functionality in typescript
|
|
// per http://stackoverflow.com/a/29803848/632495
|
|
// will need a work around.
|
|
|
|
const spec2 = {
|
|
x: (val: number, obj: any) => val + obj.y > 10
|
|
};
|
|
R.where(spec2, {x: 2, y: 7}); // => false
|
|
R.where(spec2, {x: 3, y: 8}); // => true
|
|
|
|
const xs = [{x: 2, y: 1}, {x: 10, y: 2}, {x: 8, y: 3}, {x: 10, y: 4}];
|
|
R.filter(R.where({x: 10}), xs); // ==> [{x: 10, y: 2}, {x: 10, y: 4}]
|
|
R.filter(R.where({x: 10}))(xs); // ==> [{x: 10, y: 2}, {x: 10, y: 4}]
|
|
};
|
|
|
|
() => {
|
|
// pred :: Object -> Boolean
|
|
const pred = R.whereEq({a: 1, b: 2});
|
|
pred({a: 1}); // => false
|
|
pred({a: 1, b: 2}); // => true
|
|
pred({a: 1, b: 2, c: 3}); // => true
|
|
pred({a: 1, b: 1}); // => false
|
|
R.whereEq({a: "one"}, {a: "one"}); // => true
|
|
};
|
|
|
|
() => {
|
|
const a: number[] = R.without([1, 2], [1, 2, 1, 3, 4]); // => [3, 4]
|
|
};
|
|
|
|
() => {
|
|
const mapIndexed = R.addIndex(R.map);
|
|
mapIndexed((val: string, idx: number) => `${idx}-${val}`)(["f", "o", "o", "b", "a", "r"]);
|
|
// => ['0-f', '1-o', '2-o', '3-b', '4-a', '5-r']
|
|
mapIndexed((rectangle: Rectangle, idx: number): number => rectangle.area() * idx, [new Rectangle(1, 2), new Rectangle(4, 7)]);
|
|
// => [2, 56]
|
|
};
|
|
|
|
() => {
|
|
const reduceIndexed = R.addIndex(R.reduce);
|
|
reduceIndexed((acc: string, val: string, idx: number) => `${acc},${idx}-${val}`, "", ["f", "o", "o", "b", "a", "r"]);
|
|
// => ['0-f,1-o,2-o,3-b,4-a,5-r']
|
|
};
|
|
|
|
() => {
|
|
const t = R.always("Tee");
|
|
const x: string = t(); // => 'Tee'
|
|
};
|
|
|
|
() => {
|
|
const x: number[] = R.ap([R.multiply(2), R.add(3)], [1, 2, 3]); // => [2, 4, 6, 4, 5, 6]
|
|
const y: number[] = R.ap([R.multiply(2), R.add(3)])([1, 2, 3]); // => [2, 4, 6, 4, 5, 6]
|
|
};
|
|
|
|
() => {
|
|
const nums = [1, 2, 3, -99, 42, 6, 7];
|
|
R.apply(Math.max, nums); // => 42
|
|
R.apply(Math.max)(nums); // => 42
|
|
};
|
|
|
|
() => {
|
|
interface T { sum: number; nested: { mul: number; }; }
|
|
const getMetrics = R.applySpec<T>({
|
|
sum: R.add, nested: {mul: R.multiply}
|
|
});
|
|
const result = getMetrics(2, 4); // => { sum: 6, nested: { mul: 8 } }
|
|
};
|
|
|
|
() => {
|
|
function takesThreeArgs(a: number, b: number, c: number) {
|
|
return [a, b, c];
|
|
}
|
|
|
|
takesThreeArgs.length; // => 3
|
|
takesThreeArgs(1, 2, 3); // => [1, 2, 3]
|
|
|
|
const takesTwoArgs = R.binary(takesThreeArgs);
|
|
takesTwoArgs.length; // => 2
|
|
// Only 2 arguments are passed to the wrapped function
|
|
takesTwoArgs(1, 2, 3); // => [1, 2, undefined]
|
|
};
|
|
|
|
() => {
|
|
const indentN = R.pipe(R.times(R.always(" ")),
|
|
R.join(""),
|
|
R.replace(/^(?!$)/gm)
|
|
);
|
|
|
|
const format = R.converge(
|
|
R.call, [
|
|
R.pipe(R.prop<"indent", number>("indent"), indentN),
|
|
R.prop("value")
|
|
]
|
|
);
|
|
|
|
format({indent: 2, value: "foo\nbar\nbaz\n"}); // => ' foo\n bar\n baz\n'
|
|
};
|
|
|
|
() => {
|
|
interface T { age: number; }
|
|
const cmp = R.comparator((a: T, b: T) => a.age < b.age);
|
|
const people = [
|
|
{name: "Agy", age: 33}, {name: "Bib", age: 15}, {name: "Cari", age: 16}
|
|
];
|
|
R.sort(cmp, people);
|
|
};
|
|
|
|
() => {
|
|
const people = [
|
|
{name: 'Agy', age: 33}, {name: 'Bib', age: 15}, {name: 'Cari', age: 16}
|
|
];
|
|
|
|
R.sortWith([R.ascend(R.prop('age')), R.descend(R.prop('name'))], people);
|
|
};
|
|
|
|
() => {
|
|
function add(a: number, b: number) {
|
|
return a + b;
|
|
}
|
|
|
|
function multiply(a: number, b: number) {
|
|
return a * b;
|
|
}
|
|
|
|
function subtract(a: number, b: number) {
|
|
return a - b;
|
|
}
|
|
|
|
// ≅ multiply( add(1, 2), subtract(1, 2) );
|
|
const x: number = R.converge(multiply, [add, subtract])(1, 2); // => -3
|
|
|
|
function add3(a: number, b: number, c: number) {
|
|
return a + b + c;
|
|
}
|
|
|
|
const y: number = R.converge(add3, [multiply, add, subtract])(1, 2); // => 4
|
|
};
|
|
|
|
() => {
|
|
const f0 = R.compose(Math.pow);
|
|
const f1 = R.compose(R.negate, Math.pow);
|
|
const f2 = R.compose(R.inc, R.negate, Math.pow);
|
|
const f3 = R.compose(R.inc, R.inc, R.negate, Math.pow);
|
|
const f4 = R.compose(R.inc, R.inc, R.inc, R.negate, Math.pow);
|
|
const f5 = R.compose(R.inc, R.inc, R.inc, R.inc, R.negate, Math.pow);
|
|
const x0: number = f0(3, 4); // -(3^4) + 1
|
|
const x1: number = f1(3, 4); // -(3^4) + 1
|
|
const x2: number = f2(3, 4); // -(3^4) + 1
|
|
const x3: number = f3(3, 4); // -(3^4) + 1
|
|
const x4: number = f4(3, 4); // -(3^4) + 1
|
|
const x5: number = f5(3, 4); // -(3^4) + 1
|
|
};
|
|
|
|
() => {
|
|
function fn(a: string, b: number, c: string) {
|
|
return [a, b, c];
|
|
}
|
|
|
|
const gn = R.compose(R.length, fn);
|
|
const x: number = gn("Hello", 4, "world");
|
|
};
|
|
|
|
(() => {
|
|
function Circle(r: number) {
|
|
this.r = r;
|
|
this.colors = Array.prototype.slice.call(arguments, 1);
|
|
}
|
|
|
|
Circle.prototype.area = function() { return Math.PI * Math.pow(this.r, 2); };
|
|
|
|
const circleN = R.constructN(2, Circle);
|
|
let c1 = circleN(1, "red");
|
|
const circle = R.construct(Circle);
|
|
c1 = circle(1, "red");
|
|
})();
|
|
|
|
/*****************************************************************
|
|
* Relation category
|
|
*/
|
|
() => {
|
|
const numbers = [1.0, 1.1, 1.2, 2.0, 3.0, 2.2];
|
|
const letters = R.split("", "abcABCaaaBBc");
|
|
R.countBy(Math.floor)(numbers); // => {'1': 3, '2': 2, '3': 1}
|
|
R.countBy(R.toLower)(letters); // => {'a': 5, 'b': 4, 'c': 3}
|
|
};
|
|
|
|
() => {
|
|
R.difference([1, 2, 3, 4], [7, 6, 5, 4, 3]); // => [1,2]
|
|
R.difference([7, 6, 5, 4, 3], [1, 2, 3, 4]); // => [7,6,5]
|
|
};
|
|
|
|
() => {
|
|
function cmp1(x: any, y: any) {
|
|
return x.a === y.a;
|
|
}
|
|
|
|
function cmp2(x: any, y: any) {
|
|
return x.a === y.b;
|
|
}
|
|
|
|
const l1 = [{a: 1}, {a: 2}, {a: 3}];
|
|
const l2 = [{a: 3}, {a: 4}];
|
|
const l3 = [{b: 3}, {b: 4}];
|
|
R.differenceWith(cmp1, l1, l2); // => [{a: 1}, {a: 2}]
|
|
|
|
const differenceWithCurried1 = R.differenceWith(cmp1);
|
|
differenceWithCurried1(l1, l2); // =>[{a: 1}, {a: 2}]
|
|
|
|
R.differenceWith(cmp2, l1, l3); // => [{a: 1}, {a: 2}]
|
|
};
|
|
|
|
() => {
|
|
R.equals(1, 1); // => true
|
|
R.equals("2", "1"); // => false
|
|
R.equals([1, 2, 3], [1, 2, 3]); // => true
|
|
|
|
const a: any = {};
|
|
a.v = a;
|
|
const b: any = {};
|
|
b.v = b;
|
|
R.equals(a, b); // => true
|
|
};
|
|
|
|
() => {
|
|
const a1 = R.identity(1); // => 1
|
|
const obj = {};
|
|
const a2 = R.identity([1, 2, 3]);
|
|
const a3 = R.identity(["a", "b", "c"]);
|
|
const a4 = R.identity(obj) === obj; // => true
|
|
};
|
|
|
|
() => {
|
|
const o = {};
|
|
R.identical(o, o); // => true
|
|
R.identical(1, 1); // => true
|
|
R.identical("2", "1"); // => false
|
|
R.identical([], []); // => false
|
|
R.identical(0, -0); // => false
|
|
R.identical(NaN, NaN); // => true
|
|
};
|
|
|
|
() => {
|
|
const testPath = ["x", 0, "y"];
|
|
const testObj = {x: [{y: 2, z: 3}, {y: 4, z: 5}]};
|
|
|
|
R.path(testPath, testObj); // => 2
|
|
R.path(testPath)(testObj); // => 2
|
|
|
|
R.path(['a', 'b'])({c: {b: 2}}); // => undefined
|
|
R.path(['a', 'b'], {c: {b: 2}}); // => undefined
|
|
};
|
|
|
|
() => {
|
|
const sortByAgeDescending = R.sortBy(R.compose<{}, number, number>(R.negate, R.prop("age")));
|
|
const alice = {
|
|
name: "ALICE",
|
|
age : 101
|
|
};
|
|
const bob = {
|
|
name: "Bob",
|
|
age : -10
|
|
};
|
|
const clara = {
|
|
name: "clara",
|
|
age : 314.159
|
|
};
|
|
const people = [clara, bob, alice];
|
|
sortByAgeDescending(people); // => [alice, bob, clara]
|
|
};
|
|
|
|
() => {
|
|
const sortByNameCaseInsensitive = R.sortBy(R.compose<Record<'name', string>, string, string>(R.toLower, R.prop("name")));
|
|
const alice = {
|
|
name: "ALICE",
|
|
age : 101
|
|
};
|
|
const bob = {
|
|
name: "Bob",
|
|
age : -10
|
|
};
|
|
const clara = {
|
|
name: "clara",
|
|
age : 314.159
|
|
};
|
|
const people = [clara, bob, alice];
|
|
sortByNameCaseInsensitive(people); // => [alice, bob, clara]
|
|
};
|
|
|
|
() => {
|
|
const a: number[][] = R.splitAt(1, [1, 2, 3]); // => [[1], [2, 3]]
|
|
const b: number[][] = R.splitAt(1)([1, 2, 3]); // => [[1], [2, 3]]
|
|
const c: string[] = R.splitAt(5, "hello world"); // => ['hello', ' world']
|
|
const d: string[] = R.splitAt(-1, "foobar"); // => ['fooba', 'r']
|
|
const e: string[] = R.splitAt(-1)("foobar"); // => ['fooba', 'r']
|
|
};
|
|
|
|
() => {
|
|
const a: number[][] = R.splitEvery(3, [1, 2, 3, 4, 5, 6, 7]); // => [[1, 2, 3], [4, 5, 6], [7]]
|
|
const b: number[][] = R.splitEvery(3)([1, 2, 3, 4, 5, 6, 7]); // => [[1, 2, 3], [4, 5, 6], [7]]
|
|
const c: string[] = R.splitEvery(3, 'foobarbaz'); // => ['foo', 'bar', 'baz']
|
|
const d: string[] = R.splitEvery(3)('foobarbaz'); // => ['foo', 'bar', 'baz']
|
|
};
|
|
|
|
() => {
|
|
const a: number[][] = R.splitWhen(R.equals(2), [1, 2, 3, 1, 2, 3]); // => [[1], [2, 3, 1, 2, 3]]
|
|
const b: number[][] = R.splitWhen(R.equals(2))([1, 2, 3, 1, 2, 3]); // => [[1], [2, 3, 1, 2, 3]]
|
|
};
|
|
|
|
() => {
|
|
R.startsWith("a", "abc"); // => true
|
|
R.startsWith("a")("abc"); // => true
|
|
R.startsWith(1, [1, 2, 3]); // => true
|
|
R.startsWith(1)([1, 2, 3]); // => true
|
|
R.startsWith([1], [1, 2, 3]); // => true
|
|
R.startsWith([1])([1, 2, 3]); // => true
|
|
};
|
|
|
|
() => {
|
|
R.add(2, 3); // => 5
|
|
R.add(7)(10); // => 17
|
|
R.add("Hello", " World"); // => "Hello World"
|
|
R.add("Hello")(" World"); // => "Hello World"
|
|
};
|
|
|
|
() => {
|
|
R.dec(42); // => 41
|
|
};
|
|
|
|
() => {
|
|
R.divide(71, 100); // => 0.71
|
|
|
|
const half = R.flip(R.divide)(2);
|
|
half(42); // => 21
|
|
|
|
const reciprocal = R.divide(1);
|
|
reciprocal(4); // => 0.25
|
|
};
|
|
|
|
() => {
|
|
R.gt(2, 6); // => false
|
|
R.gt(2, 0); // => true
|
|
R.gt(2, 2); // => false
|
|
R.flip(R.gt)(2)(10); // => true
|
|
R.gt(2)(10); // => false
|
|
};
|
|
|
|
() => {
|
|
R.gte(2, 6); // => false
|
|
R.gte(2, 0); // => true
|
|
R.gte(2, 2); // => false
|
|
R.flip(R.gte)(2)(10); // => true
|
|
R.gte(2)(10); // => false
|
|
};
|
|
|
|
() => {
|
|
R.isNaN(NaN); // => true
|
|
R.isNaN(undefined); // => false
|
|
R.isNaN({}); // => false
|
|
};
|
|
|
|
() => {
|
|
R.lt(2, 6); // => true
|
|
R.lt(2, 0); // => false
|
|
R.lt(2, 2); // => false
|
|
R.lt(5)(10); // => true
|
|
R.flip(R.lt)(5)(10); // => false // right-sectioned currying
|
|
};
|
|
|
|
() => {
|
|
R.lte(2, 6); // => true
|
|
R.lte(2, 0); // => false
|
|
R.lte(2, 2); // => true
|
|
R.flip(R.lte)(2)(1); // => true
|
|
R.lte(2)(10); // => true
|
|
};
|
|
|
|
() => {
|
|
R.mathMod(-17, 5); // => 3
|
|
R.mathMod(17, 5); // => 2
|
|
R.mathMod(17, -5); // => NaN
|
|
R.mathMod(17, 0); // => NaN
|
|
R.mathMod(17.2, 5); // => NaN
|
|
R.mathMod(17, 5.3); // => NaN
|
|
|
|
const clock = R.flip(R.mathMod)(12);
|
|
clock(15); // => 3
|
|
clock(24); // => 0
|
|
|
|
const seventeenMod = R.mathMod(17);
|
|
seventeenMod(3); // => 2
|
|
};
|
|
|
|
() => {
|
|
const hasName = R.has("name");
|
|
hasName({name: "alice"}); // => true
|
|
hasName({name: "bob"}); // => true
|
|
hasName({}); // => false
|
|
|
|
const point = {x: 0, y: 0};
|
|
const pointHas = R.flip(R.has)(point);
|
|
pointHas("x"); // => true
|
|
pointHas("y"); // => true
|
|
pointHas("z"); // => false
|
|
};
|
|
|
|
() => {
|
|
const x: number = R.max(7, 3); // => 7
|
|
const y: string = R.max("a", "z"); // => 'z'
|
|
};
|
|
|
|
() => {
|
|
function cmp(obj: { x: R.Ord }) {
|
|
return obj.x;
|
|
}
|
|
|
|
const a = {x: 1};
|
|
const b = {x: 2};
|
|
const c = {x: 3};
|
|
const d = {x: "a"};
|
|
const e = {x: "z"};
|
|
const f = {x: new Date(0)};
|
|
const g = {x: new Date(60 * 1000)};
|
|
R.maxBy(cmp, a, c); // => {x: 3}
|
|
R.maxBy(cmp)(a, c); // => {x: 3}
|
|
R.maxBy(cmp)(a)(b);
|
|
R.maxBy(cmp)(f)(g);
|
|
};
|
|
|
|
() => {
|
|
const a: number = R.mean([2, 7, 9]); // => 6
|
|
const b: number = R.mean([]); // => NaN
|
|
};
|
|
|
|
() => {
|
|
const a: number = R.median([7, 2, 10, 9]); // => 8
|
|
const b: number = R.median([]); // => NaN
|
|
};
|
|
|
|
() => {
|
|
const x: number = R.min(9, 3); // => 3
|
|
const y: string = R.min("a", "z"); // => 'a'
|
|
};
|
|
|
|
() => {
|
|
function cmp(obj: { x: R.Ord }) {
|
|
return obj.x;
|
|
}
|
|
|
|
const a = {x: 1};
|
|
const b = {x: 2};
|
|
const c = {x: 3};
|
|
const d = {x: "a"};
|
|
const e = {x: "z"};
|
|
const f = {x: new Date(0)};
|
|
const g = {x: new Date(60 * 1000)};
|
|
R.minBy(cmp, a, b); // => {x: 1}
|
|
R.minBy(cmp)(a, b); // => {x: 1}
|
|
R.minBy(cmp)(a)(c);
|
|
R.minBy(cmp, d, e);
|
|
R.minBy(cmp)(f)(g);
|
|
};
|
|
|
|
() => {
|
|
R.modulo(17, 3); // => 2
|
|
// JS behavior:
|
|
R.modulo(-17, 3); // => -2
|
|
R.modulo(17, -3); // => 2
|
|
|
|
const isOdd = R.flip(R.modulo)(2);
|
|
isOdd(42); // => 0
|
|
isOdd(21); // => 1
|
|
};
|
|
|
|
() => {
|
|
const double = R.multiply(2);
|
|
const triple = R.multiply(3);
|
|
double(3); // => 6
|
|
triple(4); // => 12
|
|
R.multiply(2, 5); // => 10
|
|
};
|
|
|
|
() => {
|
|
R.negate(42); // => -42
|
|
};
|
|
|
|
() => {
|
|
R.product([2, 4, 6, 8, 100, 1]); // => 38400
|
|
};
|
|
|
|
() => {
|
|
R.subtract(10, 8); // => 2
|
|
|
|
const minus5 = R.flip(R.subtract)(5);
|
|
minus5(17); // => 12
|
|
|
|
const complementaryAngle = R.subtract(90);
|
|
complementaryAngle(30); // => 60
|
|
complementaryAngle(72); // => 18
|
|
};
|
|
|
|
() => {
|
|
R.sum([2, 4, 6, 8, 100, 1]); // => 121
|
|
};
|
|
|
|
() => {
|
|
const a: number[] = R.symmetricDifference([1, 2, 3, 4], [7, 6, 5, 4, 3]); // => [1,2,7,6,5]
|
|
const b: number[] = R.symmetricDifference([7, 6, 5, 4, 3])([1, 2, 3, 4]); // => [7,6,5,1,2]
|
|
};
|
|
|
|
() => {
|
|
const eqA = R.eqBy(R.prop("a"));
|
|
const l1 = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
|
|
const l2 = [{a: 3}, {a: 4}, {a: 5}, {a: 6}];
|
|
R.symmetricDifferenceWith(eqA, l1, l2); // => [{a: 1}, {a: 2}, {a: 5}, {a: 6}]
|
|
R.symmetricDifferenceWith(eqA)(l1, l2); // => [{a: 1}, {a: 2}, {a: 5}, {a: 6}]
|
|
const c: (a: any[]) => any[] = R.symmetricDifferenceWith(eqA)(l1); // => [{a: 1}, {a: 2}, {a: 5}, {a: 6}]
|
|
};
|
|
|
|
() => {
|
|
const eqL = R.eqBy<string, number>(s => s.length);
|
|
const l1 = ['bb', 'ccc', 'dddd'];
|
|
const l2 = ['aaa', 'bb', 'c'];
|
|
R.symmetricDifferenceWith(eqL, l1, l2); // => ['dddd', 'c']
|
|
R.symmetricDifferenceWith(eqL)(l1, l2); // => ['dddd', 'c']
|
|
};
|
|
|
|
() => {
|
|
const list1 = [
|
|
{id: 1, name: 'One'},
|
|
{id: 2, name: 'Two'},
|
|
{id: 3, name: 'Three'},
|
|
{id: 4, name: 'Four'},
|
|
{id: 5, name: 'Five'}
|
|
];
|
|
|
|
const list2 = [5, 4, 6];
|
|
const matchId = (record: { id: number, name: string }, id: number): boolean => record.id === id;
|
|
|
|
R.innerJoin(matchId, list1, list2); // [{"id": 4, "name": "Four"}, {"id": 5, "name": "Five"}]
|
|
|
|
const innerJoinCurried = R.innerJoin(matchId);
|
|
innerJoinCurried(list1, list2); // [{"id": 4, "name": "Four"}, {"id": 5, "name": "Five"}]
|
|
};
|
|
|
|
/*****************************************************************
|
|
* String category
|
|
*/
|
|
() => {
|
|
R.replace("foo", "bar", "foo foo foo"); // => 'bar foo foo'
|
|
R.replace("foo", "bar")("foo foo foo"); // => 'bar foo foo'
|
|
R.replace("foo")("bar")("foo foo foo"); // => 'bar foo foo'
|
|
R.replace(/foo/, "bar", "foo foo foo"); // => 'bar foo foo'
|
|
|
|
// Use the "g" (global) flag to replace all occurrences:
|
|
R.replace(/foo/g, "bar", "foo foo foo"); // => 'bar bar bar'
|
|
R.replace(/foo/g, "bar")("foo foo foo"); // => 'bar bar bar'
|
|
R.replace(/foo/g)("bar")("foo foo foo"); // => 'bar bar bar'
|
|
|
|
// Using a function as the replacement value
|
|
R.replace(/([cfk])oo/g, (match, p1, offset) => `${p1}-${offset}`, "coo foo koo"); // => 'c0oo f4oo k8oo'
|
|
R.replace(/([cfk])oo/g, (match, p1, offset) => `${p1}-${offset}`)("coo foo koo"); // => 'c0oo f4oo k8oo'
|
|
R.replace(/([cfk])oo/g)((match, p1, offset) => `${p1}-${offset}`) ("coo foo koo"); // => 'c0oo f4oo k8oo'
|
|
};
|
|
|
|
/*****************************************************************
|
|
* Is category
|
|
*/
|
|
() => {
|
|
R.is(Object, {}); // => true
|
|
R.is(Object)({}); // => true
|
|
R.is(Number, 1); // => true
|
|
R.is(Number)(1); // => true
|
|
R.is(Object, 1); // => false
|
|
R.is(Object)(1); // => false
|
|
R.is(String, "s"); // => true
|
|
R.is(String)("s"); // => true
|
|
R.is(String, new String("")); // => true
|
|
R.is(String)(new String("")); // => true
|
|
R.is(Object, new String("")); // => true
|
|
R.is(Object)(new String("")); // => true
|
|
R.is(Object, "s"); // => false
|
|
R.is(Object)("s"); // => false
|
|
R.is(Number, {}); // => false
|
|
R.is(Number)({}); // => false
|
|
};
|
|
|
|
/*****************************************************************
|
|
* Logic category
|
|
*/
|
|
() => {
|
|
function gt10(x: number) {
|
|
return x > 10;
|
|
}
|
|
|
|
function even(x: number) {
|
|
return x % 2 === 0;
|
|
}
|
|
|
|
const f = R.allPass([gt10, even]);
|
|
f(11); // => false
|
|
f(12); // => true
|
|
};
|
|
|
|
() => {
|
|
R.and(false, true); // => false
|
|
R.and(0, []); // => 0
|
|
R.and(0)([]); // => 0
|
|
R.and(null, ""); // => null
|
|
const Why: any = ((val: boolean) => {
|
|
const why = {} as any;
|
|
why.val = val;
|
|
why.and = function(x: boolean) { return this.val && x; };
|
|
return Why;
|
|
})(true);
|
|
const why = new Why(true);
|
|
R.and(why, false); // false
|
|
};
|
|
|
|
() => {
|
|
function gt10(x: number) {
|
|
return x > 10;
|
|
}
|
|
|
|
function even(x: number) {
|
|
return x % 2 === 0;
|
|
}
|
|
|
|
const f = R.anyPass([gt10, even]);
|
|
f(11); // => true
|
|
f(8); // => true
|
|
f(9); // => false
|
|
|
|
const f2 = R.anyPass<number>([gt10, even]);
|
|
};
|
|
|
|
() => {
|
|
function gt10(x: number) {
|
|
return x > 10;
|
|
}
|
|
|
|
function even(x: number) {
|
|
return x % 2 === 0;
|
|
}
|
|
|
|
const f = R.both(gt10, even);
|
|
const g = R.both(gt10)(even);
|
|
f(100); // => true
|
|
f(101); // => false
|
|
};
|
|
|
|
() => {
|
|
function isEven(n: number) {
|
|
return n % 2 === 0;
|
|
}
|
|
|
|
const isOdd = R.complement(isEven);
|
|
isOdd(21); // => true
|
|
isOdd(42); // => false
|
|
};
|
|
|
|
(() => {
|
|
R.eqBy(Math.abs, 5, -5); // => true
|
|
});
|
|
|
|
() => {
|
|
const defaultTo42 = R.defaultTo(42);
|
|
defaultTo42(null); // => 42
|
|
defaultTo42(undefined); // => 42
|
|
defaultTo42("Ramda"); // => 'Ramda'
|
|
|
|
const valueOrUndefined = 2 as number | undefined;
|
|
defaultTo42(valueOrUndefined) - 2; // => 0
|
|
|
|
const valueOrNull = 2 as number | null;
|
|
defaultTo42(valueOrNull) - 2; // => 0
|
|
};
|
|
|
|
() => {
|
|
function gt10(x: number) {
|
|
return x > 10;
|
|
}
|
|
|
|
function even(x: number) {
|
|
return x % 2 === 0;
|
|
}
|
|
|
|
const f = R.either(gt10, even);
|
|
const g = R.either(gt10)(even);
|
|
f(101); // => true
|
|
f(8); // => true
|
|
};
|
|
|
|
() => {
|
|
// Flatten all arrays in the list but leave other values alone.
|
|
const flattenArrays = R.map(R.ifElse(Array.isArray, R.flatten, R.identity));
|
|
|
|
flattenArrays([[0], [[10], [8]], 1234, {}]); // => [[0], [10, 8], 1234, {}]
|
|
flattenArrays([[[10], 123], [8, [10]], "hello"]); // => [[10, 123], [8, 10], "hello"]
|
|
};
|
|
|
|
() => {
|
|
const incCount = R.ifElse(
|
|
R.has('count'),
|
|
R.over(R.lensProp('count'), R.inc),
|
|
R.assoc('count', 1)
|
|
);
|
|
incCount({}); // => { count: 1 }
|
|
incCount({ count: 1 }); // => { count: 2 }
|
|
R.ifElse(R.identical, R.add as (a: number, b: number) => number, R.always(""))(2, 2); // https://goo.gl/CVUSs9
|
|
};
|
|
|
|
() => {
|
|
R.isEmpty([1, 2, 3]); // => false
|
|
R.isEmpty([]); // => true
|
|
R.isEmpty(""); // => true
|
|
R.isEmpty(null); // => false
|
|
R.isEmpty({}); // =>true
|
|
R.isEmpty({a: 1}); // => false
|
|
};
|
|
|
|
() => {
|
|
R.endsWith("c", "abc"); // => true
|
|
R.endsWith("c")("abc"); // => true
|
|
R.endsWith(3, [1, 2, 3]); // => true
|
|
R.endsWith(3)([1, 2, 3]); // => true
|
|
R.endsWith([3], [1, 2, 3]); // => true
|
|
R.endsWith([3])([1, 2, 3]); // => true
|
|
};
|
|
|
|
() => {
|
|
R.not(true); // => false
|
|
R.not(false); // => true
|
|
R.not(0); // => true
|
|
R.not(1); // => false
|
|
};
|
|
|
|
class Why {
|
|
val: boolean;
|
|
|
|
constructor(val: boolean) {
|
|
this.val = val;
|
|
}
|
|
|
|
or(x: boolean) {
|
|
return this.val && x;
|
|
}
|
|
}
|
|
() => {
|
|
const x0: boolean = R.or(false, true); // => false
|
|
const x1: number | any[] = R.or(0, []); // => []
|
|
const x2: number | any[] = R.or(0)([]); // => []
|
|
const x3: string | null = R.or(null, ""); // => ''
|
|
|
|
const why = new Why(true);
|
|
why.or(true);
|
|
const x4: Why | boolean = R.or(why, false); // false
|
|
};
|
|
|
|
() => {
|
|
R.intersperse(",", ["foo", "bar"]); // => ['foo', ',', 'bar']
|
|
R.intersperse(0, [1, 2]); // => [1, 0, 2]
|
|
R.intersperse(0, [1]); // => [1]
|
|
};
|
|
|
|
() => {
|
|
R.intersection([1, 2, 3], [2, 3, 3, 4]); // => [2, 3]
|
|
R.intersection([1, 2, 3])([2, 3, 3, 4]); // => [2, 3]
|
|
};
|
|
|
|
() => {
|
|
R.bind(console.log, console);
|
|
};
|
|
|
|
// Curry tests
|