-
-
Save deepakshrma/8edd876dc7e5593587d7ee4e877959cc to your computer and use it in GitHub Desktop.
| const fill = function* (start = 0, end = 100, filter = (_) => true, mapper = (x) => x) { | |
| while (start < end) { | |
| if (filter(start)) | |
| yield start; | |
| mapper(start++); | |
| } | |
| }; | |
| const isEven = (num) => num % 2 === 0; | |
| const isOdd = (num) => num % 2 !== 0; | |
| const evens = [...fill(0, 100, isEven)]; | |
| const odds = [...fill(0, 100, isOdd)]; | |
| const evensSquares = [...fill(0, 100, isEven, (x) => x * x)]; | |
| console.log(evens); //[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98] | |
| console.log(odds); //[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99] | |
| console.log(evensSquares); //[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98] | |
| const fillNaturalNumbers = (start, end) => fill(start, end + 1); | |
| const naturals = [...fillNaturalNumbers(1, 100)]; | |
| console.log(naturals);//[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100] |
| /** | |
| * Original author @christiantakle | |
| */ | |
| const identity = <A>(a: A) => a; | |
| const constTrue = <A>(a: A) => true; | |
| interface FillInput<A> { | |
| range: [start: number, end: number]; | |
| filter: (a: number) => boolean; | |
| mapper: (a: number) => A; | |
| } | |
| function* fill<A>({ | |
| range: [start, end], | |
| filter = constTrue, | |
| mapper, | |
| }: FillInput<A>): Generator<A, void, undefined> { | |
| while (start < end) { | |
| if (filter(start)) yield mapper(start); | |
| start++; | |
| } | |
| } | |
| const isEven = (num: number) => num % 2 === 0; | |
| const isOdd = (num: number) => num % 2 !== 0; | |
| const evens = [ | |
| ...fill({ | |
| range: [1, 101], | |
| filter: isEven, | |
| mapper: identity, | |
| }), | |
| ]; | |
| console.log(evens); | |
| console.log([ | |
| ...fill({ | |
| range: [1, 101], | |
| filter: isEven, | |
| mapper: (x) => x * x, | |
| }), | |
| ]); |
Regards to:
https://gist.github.com/deepakshrma/8edd876dc7e5593587d7ee4e877959cc#gistcomment-3929109
- If you need to print natural numbers, u can write curry. Given sample works like array fill Array(n).fill(1)
Yes you are correct. It would better to just update the range input to your function rather than reimplement. Only saw it because the output was different from the author.
Sidenote:
I think that is partial function application and not currying. Most of the time the difference doesn't matter π
Simple example of a curried function.
const f = (x) => (y) => (z) => x + y + z
- filter is default version, no used of index. The default filter will always true.
I do understand what you mean and why you did it. Just seeing it because I write typescript and typed language most of the time so just mentioning for completeness.
And as you said it was never meant to be anything but javascript. I just think your code is a good basis to teach more things from.
Dumb example using a curried function to make a constTrue function.
const constant = <A,B>(a:A) => (b:B) => A
const constTrue = constant(true)
Library in which both of the above exist
https://gcanti.github.io/fp-ts/modules/function.ts.html#consttrue
- This code is not meant for typescript, Typescript version can be written as below
Very nice! π
I would change its to an object argument since you cannot use that function with a mapper and have the default filter function
const constTrue = <A>(a: A) => true;
interface FillInput {
range: [start: number, end: number];
filter: (a: number) => boolean;
mapper?: (a: number) => number;
}
function* fill({
range: [start, end],
filter = constTrue,
mapper,
}: FillInput): Generator<number, void, undefined> {
while (start < end) {
if (filter(start)) yield mapper?.(start) ?? start;
start++;
}
}
const isEven = (num: number): boolean => num % 2 === 0;
const isOdd = (num: number): boolean => num % 2 !== 0;
const evens = [
...fill({
range: [1, 101],
filter: isEven,
}),
];
console.log(evens);
console.log([
...fill({
range: [1, 101],
filter: isEven,
mapper: (x) => x * x,
}),
]);Hopefully I copy paste the correct code this time π
update
improved working in sidenote
update 2
Changed the typescript code to use the original range handling of @deepakshrma its more logical and update the range input to reflect the change.
update 3
removed generics doesn't work for mapper
update 4
add return type to fill fn
Re-add generics but it forces you to provided a mapper fn on every call
const identity = <A>(a: A) => a;
const constTrue = <A>(a: A) => true;
interface FillInput<A> {
range: [start: number, end: number];
filter: (a: number) => boolean;
mapper: (a: number) => A;
}
function* fill<A>({
range: [start, end],
filter = constTrue,
mapper,
}: FillInput<A>): Generator<A, void, undefined> {
while (start < end) {
if (filter(start)) yield mapper(start);
start++;
}
}
const isEven = (num: number): boolean => num % 2 === 0;
const isOdd = (num: number): boolean => num % 2 !== 0;
const evens = [
...fill({
range: [1, 101],
filter: isEven,
mapper: identity,
}),
];
console.log(evens);
console.log([
...fill({
range: [1, 101],
filter: isEven,
mapper: (x) => "changes the output type",
}),
]);I tried something similar to write, However, the default to mapper still issue.
Type 'number' is not assignable to type 'A'.
If that could be solve.
@deepakshrma I've updated my first comment with information from our dialog. I removed the generics from the example where mapper is optional you cannot typecheck it unless you use any or unknown neither which is ideal.
I've also added an example with generics but you have to supply a mapper function to use it to make the type checker happy
@christiantakle : haha! no worries.. Reviews make code better ;)