import { encapsulateOpState } from "./encapsulateOpState"; import { invokeOperator } from "./invokeOperator"; import { Operator } from "../types/Operator"; import { id } from "../../tools/typeSafety/id"; function f_o_g( op1: Operator, op2: Operator ): Operator.fλ.Stateless { const opAtoB = Operator.fλ.Stateful.match(op1) ? encapsulateOpState(op1) : id>(op1) ; const opBtoC = Operator.fλ.Stateful.match(op2) ? encapsulateOpState(op2) : id>(op2) ; return id>( (...[dataA, , cbInvokedIfMatched]) => { const resultB = invokeOperator( opAtoB, dataA, cbInvokedIfMatched ); if (Operator.fλ.Result.NotMatched.match(resultB)) { return resultB; } const [dataB] = resultB; return invokeOperator( opBtoC, dataB, cbInvokedIfMatched ); } ); } export function compose( op1: Operator.fλ, op2: Operator.fλ ): Operator.fλ.Stateless; export function compose( op1: Operator.fλ, op2: (data: B) => data is C, ): Operator.fλ.Stateless; export function compose( op1: Operator.fλ, op2: (data: B) => boolean, ): Operator.fλ.Stateless; export function compose( op1: (data: A) => data is B, op2: Operator.fλ ): Operator.fλ.Stateless; export function compose( op1: (data: A) => boolean, op2: Operator.fλ ): Operator.fλ.Stateless; export function compose( op1: (data: A) => data is B, op2: (data: B) => data is C, ): Operator.fλ.Stateless; export function compose( op1: (data: A) => data is B, op2: (data: B) => boolean, ): Operator.fλ.Stateless; export function compose( op1: (data: A) => boolean, op2: (data: A) => data is B ): Operator.fλ.Stateless; export function compose( op1: (data: A) => boolean, op2: (data: A) => boolean, ): Operator.fλ.Stateless; export function compose( op1: Operator.fλ, op2: Operator.fλ, op3: Operator.fλ ): Operator.fλ.Stateless; export function compose( op1: Operator.fλ, op2: Operator.fλ, op3: Operator.fλ, op4: Operator.fλ ): Operator.fλ.Stateless; export function compose( op1: Operator.fλ, op2: Operator.fλ, op3: Operator.fλ, op4: Operator.fλ ): Operator.fλ.Stateless; export function compose( op1: Operator.fλ, op2: Operator.fλ, op3: Operator.fλ, op4: Operator.fλ, op5: Operator.fλ, ): Operator.fλ.Stateless; export function compose( op1: Operator, op2: Operator ): Operator.fλ.Stateless; export function compose( op1: Operator, op2: Operator, op3: Operator ): Operator.fλ.Stateless; export function compose( op1: Operator, op2: Operator, op3: Operator, op4: Operator, ): Operator.fλ.Stateless; export function compose( op1: Operator, op2: Operator, op3: Operator, op4: Operator, op5: Operator ): Operator.fλ.Stateless; export function compose( ...ops: [ Operator, ...Operator[] ] ): Operator.Stateless; export function compose( ...ops: [ Operator, ...Operator[] ] ): Operator.Stateless { if (ops.length === 1) { const [op] = ops; return Operator.fλ.Stateful.match(op) ? encapsulateOpState(op) : op ; } const [op1, op2, ...rest] = ops; const op1_o_op2 = f_o_g(op1, op2); if (rest.length === 0) { return op1_o_op2; } return compose(op1_o_op2, ...rest); } /* opCompose( (data: string)=> [ data.length ], data => [ `${data}` ] ); opCompose( (data: string)=> true, (data)=> [ data.length ], ); opCompose( (data: string)=> [ data.length ], (data)=> true, ); opCompose( (data: string)=> true, data=> true, ); opCompose( (data: string | number): data is string => true, data=> [ data.length ] ); opCompose( (data: string | number | Function ): data is (string | Function) => true, (data): data is Function=> true ); opCompose( (data: string | number | Function ): data is (string | Function) => true, data => typeof data === "string" ? [ data ] : null ); opCompose( (data: string | number | Function ): data is (string | Function) => true, data => true ); opCompose( (data: string | number | Function) => true, (data): data is (string | Function) => true, ); opCompose( (data: string) => [ data.length > 3 ? data.length : data ], (data): data is string => true, ); opCompose( id>((data: string) => true), id>((data: string) => [data.length] as const) ); opCompose( id>( (data: string) => true ), id>( (data) => [data.length] ), id>( data => [`${data}`] ) ); opCompose( (data: string)=> [data], data => [data], data => [data] ); opCompose( (data: string)=> [ data], data => [ data ], data => [ data ], data => [ data ], data => [ data ] ); */