IxJS
IxJS copied to clipboard
Curried and args switched
Would be nice to have some methods curried (and because of that switched arguments) to align with FP style.
Example:
// Current
const results = of(1, 2, 3)
.chain(source => filter(source, x => x % 2 === 0))
.chain(source => map(source, x => x * x));
// Possible with args switched (and curried)
const results = of(1, 2, 3)
.chain(filter(x => x % 2 === 0))
.chain(map(x => x * x));
@dacz I agree it would be nice, will investigate for an FP variant
can we also support _.flow
or provide a flow/compose function:
// Current
const results = of(1, 2, 3)
.chain(source => filter(source, x => x % 2 === 0))
.chain(source => map(source, x => x * x));
import * as ix from 'ix/fp/es';
import flow from 'lodash.flow';
// Possible with args switched (and curried)
const results = ix.flow(
v => ix.of(...v),
ix.filter(x => x % 2 === 0),
ix.map(x => x * x),
)([1, 2, 3]);
assert(ix.flow === flow);
@dacz @graingert is the pipe
mechanism we have good enough or do we need more?
@mattpodwysocki I'd like to be able to use a flow function to create other functions:
import * as ix from 'ix/fp/es';
const process = ix.flow(
v => ix.of(...v),
ix.filter(x => x % 2 === 0),
ix.map(x => x * x),
);
process([1, 2, 3]); // a new iterable.
(eg I'd like to be able to use the whole of IxJS without ever calling a method, or worrying about this
)
and if/when |>
is released I'd like to be able to use that.
import * as ix from 'ix/fp/es';
const process = v => ix.of(...v)
|> ix.filter(x => x % 2 === 0)
|> ix.map(x => x * x)
);
process([1, 2, 3]); // a new iterable.
@graingert that's already supported since source
would be the first applied argument as described in the proposal
import { AsyncIterableX as AsyncIterable } from 'ix';
import { map, filter } from 'ix/asynciterable';
const process = v => AsyncIterable.of(...v)
|> _ => filter(_, x => x % 2 === 0)
|> _ => map(_, x => x * x)
);
process([1, 2, 3]);
Or you can use the pipe
operators.
import { AsyncIterableX as AsyncIterable } from 'ix';
import { map, filter } from 'ix/asynciterable/pipe';
const process = v => AsyncIterable.of(...v)
|> filter(x => x % 2 === 0)
|> map(x => x * x)
);
process([1, 2, 3]);
@mattpodwysocki ah good stuff. how about a single namespace to import from?
@graingert that's why we have an index.ts
in each area root for just that purpose, as well as the piped.
@mattpodwysocki I mean the whole library in fp/pipe form. Currently you're doing it like:
import { AsyncIterableX as AsyncIterable } from 'ix';
import { map, filter } from 'ix/asynciterable/pipe';
I want:
import { * as ix } from 'ix/fp';
@graingert the present structure is in place to support all three styles. At a minimum operators for the iterable/asyncIterable will stay separate, since they share names. Importing everything from the root is convenient, but won't tree shake.