IxJS icon indicating copy to clipboard operation
IxJS copied to clipboard

Curried and args switched

Open dacz opened this issue 7 years ago • 10 comments

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 avatar Jul 22 '17 11:07 dacz

@dacz I agree it would be nice, will investigate for an FP variant

mattpodwysocki avatar Aug 17 '17 01:08 mattpodwysocki

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);

graingert avatar Oct 04 '17 22:10 graingert

@dacz @graingert is the pipe mechanism we have good enough or do we need more?

mattpodwysocki avatar Nov 06 '17 16:11 mattpodwysocki

@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)

graingert avatar Nov 06 '17 16:11 graingert

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 avatar Nov 06 '17 16:11 graingert

@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 avatar Nov 06 '17 16:11 mattpodwysocki

@mattpodwysocki ah good stuff. how about a single namespace to import from?

graingert avatar Nov 06 '17 16:11 graingert

@graingert that's why we have an index.ts in each area root for just that purpose, as well as the piped.

mattpodwysocki avatar Nov 06 '17 16:11 mattpodwysocki

@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 avatar Nov 06 '17 17:11 graingert

@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.

trxcllnt avatar Nov 06 '17 18:11 trxcllnt