Commit be3abc83 by Vladislav Lagunoff

[update] Добавлен Difference

parent fd01e2ae
...@@ -12,10 +12,10 @@ Update.Do = Do; ...@@ -12,10 +12,10 @@ Update.Do = Do;
declare module "./" { declare module "./" {
interface UpdateStatic { interface UpdateStatic {
Do<State, Result>(iter: () => IterableIterator<Update<any, any>>): Update<State, Result>; Do<State, Result>(iter: () => IterableIterator<Update<Error, any, any>>): Update<Error, State, Result>;
} }
interface BoundStatics<State> { interface BoundStatics<Error, State> {
Do<Result>(iter: () => IterableIterator<Update<any, any>>): Update<State, Result>; Do<Result>(iter: () => IterableIterator<Update<Error, any, any>>): Update<Error, State, Result>;
} }
} }
......
...@@ -5,23 +5,32 @@ import { absurd } from '../types'; ...@@ -5,23 +5,32 @@ import { absurd } from '../types';
// ADT // ADT
export type Update<State, A> = export type Update<Error, State, A> =
| Pure<State, A> // { value: A } | Pure<Error, State, A> // { value: A }
| Modify<State, A> // { proj(x: State): State } // A ~ void | Modify<Error, State, A> // { proj(x: State): State } // A ~ void
| Patch<State, A> // { patch: Partial<State> } // A ~ void | Patch<Error, State, A> // { patch: Partial<State> } // A ~ void
| Get<State, A> // { tag: 'Get' } // A ~ State | Get<Error, State, A> // { tag: 'Get' } // A ~ State
| Children<State, A> // { key: ControlledComponent<any, any>, update: Update<any, A> } | Children<Error, State, A> // { component: React.Component<any, any>, update: Update<any, A> }
| Effect<State, A> // { effect: Eff<never, A> } | Effect<Error, State, A> // { effect: Eff<never, A> }
| FromPromise<State, A> // { promise: Promise<A> } | FromPromise<Error, State, A> // { promise: Promise<A> }
| Chain<State, A> // { update: Update<State, any>, chain(x: any): Update<State, A> } | Chain<Error, State, A> // { update: Update<Error, State, any>, chain(x: any): Update<Error, State, A> }
| Apply<State, A> // { args: Update<State, any>[], proj(...args): A } | Apply<Error, State, A> // { args: Update<Error, State, any>[], proj(...args): A }
| Batch<State, A> // { steps: Updte<State, any>[] } | Batch<Error, State, A> // { steps: Updte<Error, State, any>[] }
| Concat<State, A> // { steps: Updte<State, any>[] } | Concat<Error, State, A> // { steps: Updte<Error, State, any>[] }
| Difference<Error, State, A> // { update: Update<A>, difference(prev: State, next: State): State|Update<Error, State, void> }
; ;
export type AnyUpdate = Update<any, any, any>;
// Perform state update // Perform state update
export function go<State, A>(update: Update<State, A>, component: React.Component<any, State>, onNext: (x: A) => void, onComplete: () => void): () => void { export function go<Error, State, A>(
update: Update<Error, State, A>,
getState: () => State,
setState: SetState<State>,
onNext: (x: A) => void,
onError: (x: Error) => void,
onComplete: () => void
): Canceller {
if (update instanceof Pure) { if (update instanceof Pure) {
onNext(update.value); onNext(update.value);
onComplete(); onComplete();
...@@ -29,7 +38,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -29,7 +38,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
} }
if (update instanceof Modify) { if (update instanceof Modify) {
component['updater'].enqueueSetState(component, update.proj, () => { setState(update.proj, () => {
onNext(void 0 as any); onNext(void 0 as any);
update.callback && update.callback(); update.callback && update.callback();
onComplete(); onComplete();
...@@ -38,7 +47,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -38,7 +47,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
} }
if (update instanceof Patch) { if (update instanceof Patch) {
component['updater'].enqueueSetState(component, update.patch, () => { setState(update.patch, () => {
onNext(void 0 as any); onNext(void 0 as any);
update.callback && update.callback(); update.callback && update.callback();
onComplete(); onComplete();
...@@ -47,17 +56,19 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -47,17 +56,19 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
} }
if (update instanceof Get) { if (update instanceof Get) {
onNext(component.state as any); onNext(getState() as any as A);
onComplete(); onComplete();
return noopFunc; return noopFunc;
} }
if (update instanceof Children) { if (update instanceof Children) {
return go(update.update, update.component, onNext, onComplete); const _getState = () => update.component.state;
const _setState: SetState<any> = (projOrPatch, cb?) => update.component['updater'].enqueueSetState(update.component, projOrPatch, cb);
return go(update.update, _getState, _setState, onNext, onError, onComplete);
} }
if (update instanceof Effect) { if (update instanceof Effect) {
return update.effect.run(onNext as any, onComplete); return update.effect.run(ethr => ethr.fold(onError, onNext), onComplete);
} }
if (update instanceof FromPromise) { if (update instanceof FromPromise) {
...@@ -66,23 +77,27 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -66,23 +77,27 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
} }
if (update instanceof Chain) { if (update instanceof Chain) {
const subscriptions: Array<Function|null> = []; const cancellers = new Map<AnyUpdate, Canceller>();
subscriptions.push(go(update.update, component, result => { const handleUpdate = (u: AnyUpdate) => {
const idx = subscriptions.length; const _onNext = result => {
subscriptions.push(go(update.andThen(result), component, onNext, () => { if (u === update.update) handleUpdate(update.andThen(result));
subscriptions[idx] = null; else onNext(result);
for (const unsub of subscriptions) if (unsub !== null) return; };
onComplete(); const _onComplete = () => {
})); if (!cancellers.has(u)) completedImmediately = true;
}, () => { cancellers.delete(u);
subscriptions[0] = null; if (cancellers.size === 0) onComplete();
for (const unsub of subscriptions) if (unsub !== null) return; };
onComplete(); let completedImmediately = false;
}));
const canceller = go(u, getState, setState as any, _onNext, onError, _onComplete);
if (!completedImmediately) cancellers.set(u, canceller);
};
handleUpdate(update.update);
if (cancellers.size === 0) return noopFunc;
return () => subscriptions.forEach( return () => cancellers.forEach(canceller => canceller());
funOrNull => funOrNull ? funOrNull() : void 0
);
} }
if (update instanceof Apply) { if (update instanceof Apply) {
...@@ -107,7 +122,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -107,7 +122,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
}; };
update.args.forEach((u, idx) => { update.args.forEach((u, idx) => {
const canceller = go(u, component, next(idx), complete(idx)); const canceller = go(u, getState, setState, next(idx), onError, complete(idx));
if (subscriptions[idx] !== null) subscriptions[idx] = canceller; if (subscriptions[idx] !== null) subscriptions[idx] = canceller;
}); });
...@@ -125,7 +140,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -125,7 +140,7 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
onNext(void 0 as any); onNext(void 0 as any);
onComplete(); // If control flow reaches here, that means all nested commands are completed onComplete(); // If control flow reaches here, that means all nested commands are completed
}; };
subscriptions = update.steps.map((u, idx) => go(u, component, noopFunc, loop(idx))); subscriptions = update.steps.map((u, idx) => go(u, getState, setState, noopFunc, onError, loop(idx)));
return () => subscriptions.forEach( return () => subscriptions.forEach(
funOrNull => funOrNull ? funOrNull() : void 0 funOrNull => funOrNull ? funOrNull() : void 0
...@@ -137,180 +152,239 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen ...@@ -137,180 +152,239 @@ export function go<State, A>(update: Update<State, A>, component: React.Componen
const loop = idx => () => { const loop = idx => () => {
// If condition holds, then all nested effects are completed, therefore we're done // If condition holds, then all nested effects are completed, therefore we're done
if (idx >= update.steps.length) { onNext(void 0 as any); onComplete(); return; } if (idx >= update.steps.length) { onNext(void 0 as any); onComplete(); return; }
unsubscribe = go(update.steps[idx], component, noopFunc, loop(idx + 1)); unsubscribe = go(update.steps[idx], getState, setState, noopFunc, onError, loop(idx + 1));
}; };
loop(0); loop(0);
return () => unsubscribe ? unsubscribe() : void 0; return () => unsubscribe ? unsubscribe() : void 0;
} }
if (update instanceof Difference) {
const cancellers = new Map<AnyUpdate, Canceller>();
const _setState: SetState<State> = (patchOrProj, cb?) => {
const prev = getState();
// @ts-ignore
const next = typeof(patchOrProj) === 'function' ? patchOrProj(prev) : { ...prev, ...patchOrProj };
const stateOrUpdate = update.difference(prev, next);
if (stateOrUpdate instanceof UpdateBase) {
handleUpdate(stateOrUpdate);
} else {
setState(() => stateOrUpdate, cb);
}
};
const handleUpdate = (u: AnyUpdate) => {
const _onNext = result => {
if (u === update.update) onNext(result);
// Just ignore `void` result from spawned processes
};
const _onComplete = () => {
if (!cancellers.has(u)) completedImmediately = true;
cancellers.delete(u);
if (cancellers.size === 0) onComplete();
};
let completedImmediately = false;
const canceller = go(u, getState, u === update.update ? _setState : setState as any, _onNext, onError, _onComplete);
if (!completedImmediately) cancellers.set(u, canceller);
};
handleUpdate(update.update);
if (cancellers.size === 0) return noopFunc;
return () => cancellers.forEach(canceller => canceller());
}
return absurd(update); return absurd(update);
} }
// Instance methods // Instance methods
export class UpdateBase<State, A> { export class UpdateBase<Error, State, A> {
readonly _Error: Error;
readonly _State: State; readonly _State: State;
readonly _A: A; readonly _A: A;
map<B>(proj: (x: A) => B): Apply<State, B> { map<B>(proj: (x: A) => B): Apply<Error, State, B> {
const self = this as any as Update<State, A>; const self = this as any as Update<Error, State, A>;
return new Apply<State, B>([self], proj); return new Apply<Error, State, B>([self], proj);
} }
mapTo<B>(value: B): Apply<State, B> { mapTo<B>(value: B): Apply<Error, State, B> {
const self = this as any as Update<State, A>; const self = this as any as Update<Error, State, A>;
return new Apply<State, B>([self], () => value); return new Apply<Error, State, B>([self], () => value);
} }
chain<B,State2>(andThen: (x: A) => Update<State2, B>): Chain<State&State2, B>; chain<B,State2>(andThen: (x: A) => Update<Error, State2, B>): Chain<Error, State&State2, B>;
chain<B>(andThen: (x: A) => Update<State, B>): Chain<State, B>; chain<B>(andThen: (x: A) => Update<Error, State, B>): Chain<Error, State, B>;
chain<B>(andThen: (x: A) => Update<State, B>): Chain<State, B> { chain<B>(andThen: (x: A) => Update<Error, State, B>): Chain<Error, State, B> {
const self = this as any as Update<State, A>; const self = this as any as Update<Error, State, A>;
return new Chain<State, B>(self, andThen); return new Chain<Error, State, B>(self, andThen);
} }
chainTo<B,State2>(value: Update<State2, B>): Chain<State&State2, B>; chainTo<B,State2>(value: Update<Error, State2, B>): Chain<Error, State&State2, B>;
chainTo<B>(value: Update<State, B>): Chain<State, B>; chainTo<B>(value: Update<Error, State, B>): Chain<Error, State, B>;
chainTo<B>(value: Update<State, B>): Chain<State, B> { chainTo<B>(value: Update<Error, State, B>): Chain<Error, State, B> {
const self = this as any as Update<State, A>; const self = this as any as Update<Error, State, A>;
return new Chain<State, B>(self, () => value); return new Chain<Error, State, B>(self, () => value);
} }
run(component: React.Component<any, State>, onNext?: (x: A) => void, onComplete?: () => void): () => void { run(component: React.Component<any, State>, onNext?: (x: A) => void, onError?: (x: Error) => void, onComplete?: () => void): Canceller {
const self = this as any as Update<State, A>; const self = this as any as Update<Error, State, A>;
return go(self, component, onNext || noopFunc, onComplete || noopFunc); const getState = () => component.state;
const setState: SetState<State> = (projOrPatch, cb?) => component['updater'].enqueueSetState(component, projOrPatch, cb);
return go(self, getState, setState, onNext || noopFunc, onError || noopFunc, onComplete || noopFunc);
} }
pending(): Update<State & { pending: boolean }, A> { pending(): Update<Error, State & { pending: boolean }, A> {
// @ts-ignore // @ts-ignore
return patch({ pending: true }).chainTo(this.chain(value => patch({ pending: false }).mapTo(value))); return patch({ pending: true }).chainTo(this.chain(value => patch({ pending: false }).mapTo(value)));
} }
} }
export function ap<State,A,B>(a: Update<State,A>, f: (a: A) => B): Update<State,B>; // SetState
export function ap<State,A,B,C>(a: Update<State,A>, b: Update<State,B>, f: (a: A, b: B) => C): Update<State,C>; export type SetState<State> = {
export function ap<State,A,B,C,D>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, f: (a: A, b: B, c: C) => D): Update<State,D>; (patch: Partial<State>, cb?: () => void): void;
export function ap<State,A,B,C,D,E>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, d: Update<State,D>, f: (a: A, b: B, c: C, d: D) => E): Update<State,E>; (proj: (x: State) => State, cb?: () => void): void;
export function ap<State,A,B,C,D,E,F>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, d: Update<State,D>, e: Update<State,E>, f: (a: A, b: B, c: C, d: D, e: E) => F): Update<State,F>; };
export function ap<State,A,B,C,D,E,F,G>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, d: Update<State,D>, e: Update<State,E>, f_: Update<State,F>, f: (a: A, b: B, c: C, d: D, e: E, f: F) => G): Update<State,G>;
export function ap(): Update<unknown, unknown> {
export function ap<Error, State,A,B>(a: Update<Error, State,A>, f: (a: A) => B): Update<Error, State,B>;
export function ap<Error, State,A,B,C>(a: Update<Error, State,A>, b: Update<Error, State,B>, f: (a: A, b: B) => C): Update<Error, State,C>;
export function ap<Error, State,A,B,C,D>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, f: (a: A, b: B, c: C) => D): Update<Error, State,D>;
export function ap<Error, State,A,B,C,D,E>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, d: Update<Error, State,D>, f: (a: A, b: B, c: C, d: D) => E): Update<Error, State,E>;
export function ap<Error, State,A,B,C,D,E,F>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, d: Update<Error, State,D>, e: Update<Error, State,E>, f: (a: A, b: B, c: C, d: D, e: E) => F): Update<Error, State,F>;
export function ap<Error, State,A,B,C,D,E,F,G>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, d: Update<Error, State,D>, e: Update<Error, State,E>, f_: Update<Error, State,F>, f: (a: A, b: B, c: C, d: D, e: E, f: F) => G): Update<Error, State,G>;
export function ap(): Update<unknown, unknown, unknown> {
const args = Array.prototype.slice.call(arguments, 0, arguments.length - 1); const args = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
const proj = arguments[arguments.length - 1]; const proj = arguments[arguments.length - 1];
return new Apply(args, proj); return new Apply(args, proj);
} }
export function of<A>(value: A): Pure<never, A> { export function of<A>(value: A): Pure<never, {}, A> {
return new Pure(value); return new Pure(value);
} }
export function patch<State>(patch: Partial<State>, callback?: () => void): Patch<State, void> { export function patch<State>(patch: Partial<State>, callback?: () => void): Patch<never, State, void> {
return new Patch(patch, callback); return new Patch(patch, callback);
} }
export function modify<State>(proj: (x: State) => State, callback?: () => void): Modify<State, void> { export function modify<State>(proj: (x: State) => State, callback?: () => void): Modify<never, State, void> {
return new Modify(proj, callback); return new Modify(proj, callback);
} }
export function effect<Error, Success>(eff: Eff<Error, Success>): Effect<{}, Either<Error, Success>> { export function effect<Error, Success>(eff: Eff<Error, Success>): Effect<Error, {}, Success> {
return new Effect(eff as any); return new Effect(eff as any);
} }
export function batch<State>(...steps: Update<State, any>[]): Batch<State, void>; export function batch<Error, State>(...steps: Update<Error, State, any>[]): Batch<Error, State, void>;
export function batch<State>(steps: Update<State, any>[]): Batch<State, void>; export function batch<Error, State>(steps: Update<Error, State, any>[]): Batch<Error, State, void>;
export function batch(): Batch<unknown, void> { export function batch(): Batch<never, unknown, void> {
const steps = Array.isArray(arguments[0]) ? arguments[0] : arguments; const steps = Array.isArray(arguments[0]) ? arguments[0] : arguments;
return new Batch(steps); return new Batch(steps);
} }
export function concat<State>(...steps: Update<State, any>[]): Concat<State, void>; export function concat<Error, State>(...steps: Update<Error, State, any>[]): Concat<Error, State, void>;
export function concat<State>(steps: Update<State, any>[]): Concat<State, void>; export function concat<Error, State>(steps: Update<Error, State, any>[]): Concat<Error, State, void>;
export function concat(): Concat<unknown, void> { export function concat(): Concat<never, unknown, void> {
const steps = Array.isArray(arguments[0]) ? arguments[0] : arguments; const steps = Array.isArray(arguments[0]) ? arguments[0] : arguments;
return new Concat(steps); return new Concat(steps);
} }
export function difference<Error, State, A>(update: Update<Error, State, A>, diff: (prev: State, next: State) => State|Update<Error, State, void>): Difference<Error, State, A> {
return new Difference(update, diff);
}
class Pure<State, A> extends UpdateBase<State, A> { class Pure<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly value: A, readonly value: A,
) { super(); } ) { super(); }
} }
class Modify<State, A> extends UpdateBase<State, A> { class Modify<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly proj: (x: State) => State, readonly proj: (x: State) => State,
readonly callback?: () => void, readonly callback?: () => void,
) { super(); } ) { super(); }
} }
class Patch<State, A> extends UpdateBase<State, A> { class Patch<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly patch: Partial<State>, readonly patch: Partial<State>,
readonly callback?: () => void, readonly callback?: () => void,
) { super(); } ) { super(); }
} }
class Get<State, A> extends UpdateBase<State, A> { class Get<Error, State, A> extends UpdateBase<Error, State, A> {
} }
class Children<State, A> extends UpdateBase<State, A> { class Children<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly component: React.Component<any, any>, readonly component: React.Component<any, any>,
readonly update: Update<any, A> readonly update: Update<never, {}, A>
) { super(); } ) { super(); }
} }
class Effect<State, A> extends UpdateBase<State, A> { class Effect<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly effect: Eff<never, A>, readonly effect: Eff<Error, A>,
) { super(); } ) { super(); }
} }
class FromPromise<State, A> extends UpdateBase<State, A> { class FromPromise<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly promise: () => Promise<A>, readonly promise: () => Promise<A>,
) { super(); } ) { super(); }
} }
class Chain<State, A> extends UpdateBase<State, A> { class Chain<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly update: Update<State, any>, readonly update: Update<Error, State, any>,
readonly andThen: (x: any) => Update<State, A>, readonly andThen: (x: any) => Update<Error, State, A>,
) { super(); } ) { super(); }
} }
class Apply<State, A> extends UpdateBase<State, A> { class Apply<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly args: Update<State, any>[], readonly args: Update<Error, State, any>[],
readonly proj: (...args) => A, readonly proj: (...args) => A,
) { super(); } ) { super(); }
} }
class Batch<State, A> extends UpdateBase<State, A> { class Batch<Error, State, A> extends UpdateBase<Error, State, A> {
constructor(
readonly steps: Update<Error, State, any>[],
) { super(); }
}
class Concat<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly steps: Update<State, any>[], readonly steps: Update<Error, State, any>[],
) { super(); } ) { super(); }
} }
class Concat<State, A> extends UpdateBase<State, A> { class Difference<Error, State, A> extends UpdateBase<Error, State, A> {
constructor( constructor(
readonly steps: Update<State, any>[], readonly update: Update<Error, State, A>,
readonly difference: (prev: State, next: State) => State|Update<Error, State, void>,
) { super(); } ) { super(); }
} }
// Functional helpers // Functional helpers
const noopFunc = () => {}; const noopFunc = () => {};
export type Canceller = () => void;
export const get = new Get(); export const get = new Get<never, {}, void>();
export class Component<Props, State> extends React.Component<Props, State> { export class Component<Error, Props, State> extends React.Component<Props, State> {
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
// @ts-ignore // @ts-ignore
...@@ -321,7 +395,7 @@ export class Component<Props, State> extends React.Component<Props, State> { ...@@ -321,7 +395,7 @@ export class Component<Props, State> extends React.Component<Props, State> {
state: ((prevState: Readonly<State>, props: Readonly<Props>) => (Pick<State, K> | State | null)) | (Pick<State, K> | State | null), state: ((prevState: Readonly<State>, props: Readonly<Props>) => (Pick<State, K> | State | null)) | (Pick<State, K> | State | null),
callback?: () => void callback?: () => void
): void; ): void;
setState(update: Update<State, void>, callback?: () => void): void; setState(update: Update<Error, State, void>, callback?: () => void): void;
setState(updateOrProjOrPatch, callback?) { setState(updateOrProjOrPatch, callback?) {
if (updateOrProjOrPatch instanceof UpdateBase) { if (updateOrProjOrPatch instanceof UpdateBase) {
const onUpdate = this.props['onUpdate'] as unknown; const onUpdate = this.props['onUpdate'] as unknown;
...@@ -334,9 +408,9 @@ export class Component<Props, State> extends React.Component<Props, State> { ...@@ -334,9 +408,9 @@ export class Component<Props, State> extends React.Component<Props, State> {
} }
if (typeof(updateOrProjOrPatch) === 'function') { if (typeof(updateOrProjOrPatch) === 'function') {
return this.setState(new Modify<State, void>(updateOrProjOrPatch, callback)) return this.setState(new Modify<Error, State, void>(updateOrProjOrPatch, callback))
} else { } else {
return this.setState(new Patch<State, void>(updateOrProjOrPatch, callback)) return this.setState(new Patch<Error, State, void>(updateOrProjOrPatch, callback))
} }
} }
} }
...@@ -368,26 +442,26 @@ export const Update = { ...@@ -368,26 +442,26 @@ export const Update = {
bind, bind,
} as UpdateStatic; } as UpdateStatic;
export interface BoundStatics<State> { export interface BoundStatics<Error, State> {
ap<A,B,C>(a: Update<State,A>, b: Update<State,B>, f: (a: A, b: B) => C): Apply<State,C>; ap<A,B,C>(a: Update<Error, State,A>, b: Update<Error, State,B>, f: (a: A, b: B) => C): Apply<Error, State,C>;
ap<A,B,C,D>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, f: (a: A, b: B, c: C) => D): Apply<State,D>; ap<A,B,C,D>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, f: (a: A, b: B, c: C) => D): Apply<Error, State,D>;
ap<A,B,C,D,E>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, d: Update<State,D>, f: (a: A, b: B, c: C, d: D) => E): Apply<State,E>; ap<A,B,C,D,E>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, d: Update<Error, State,D>, f: (a: A, b: B, c: C, d: D) => E): Apply<Error, State,E>;
ap<A,B,C,D,E,F>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, d: Update<State,D>, e: Update<State,E>, f: (a: A, b: B, c: C, d: D, e: E) => F): Apply<State,F>; ap<A,B,C,D,E,F>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, d: Update<Error, State,D>, e: Update<Error, State,E>, f: (a: A, b: B, c: C, d: D, e: E) => F): Apply<Error, State,F>;
ap<A,B,C,D,E,F,G>(a: Update<State,A>, b: Update<State,B>, c: Update<State,C>, d: Update<State,D>, e: Update<State,E>, f_: Update<State,F>, f: (a: A, b: B, c: C, d: D, e: E, f: F) => G): Apply<State,G>; ap<A,B,C,D,E,F,G>(a: Update<Error, State,A>, b: Update<Error, State,B>, c: Update<Error, State,C>, d: Update<Error, State,D>, e: Update<Error, State,E>, f_: Update<Error, State,F>, f: (a: A, b: B, c: C, d: D, e: E, f: F) => G): Apply<Error, State,G>;
batch(...steps: Update<State, any>[]): Batch<State, void>; batch(...steps: Update<Error, State, any>[]): Batch<Error, State, void>;
batch(steps: Update<State, any>[]): Batch<State, void>; batch(steps: Update<Error, State, any>[]): Batch<Error, State, void>;
concat(...steps: Update<State, any>[]): Concat<State, void>; concat(...steps: Update<Error, State, any>[]): Concat<Error, State, void>;
concat(steps: Update<State, any>[]): Concat<State, void>; concat(steps: Update<Error, State, any>[]): Concat<Error, State, void>;
of<A>(value: A): Pure<State,A>; of<A>(value: A): Pure<Error, State, A>;
patch(patch: Partial<State>, callback?: () => void): Patch<State, void>; patch(patch: Partial<State>, callback?: () => void): Patch<Error, State, void>;
modify(proj: (x: State) => State, callback?: () => void): Modify<State, void>; modify(proj: (x: State) => State, callback?: () => void): Modify<Error, State, void>;
effect<Error, Success>(eff: Eff<Error, Success>): Effect<State, Either<Error, Success>>; effect<Error, Success>(eff: Eff<Error, Success>): Effect<Error, State, Success>;
get: Get<State, State>; get: Get<Error, State, State>;
} }
export function bind<State>() { export function bind<Error, State>() {
return Update as any as BoundStatics<State>; return Update as any as BoundStatics<Error, State>;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment