<commit_before>﻿interface Converter<TIn, TOut> {
    (item: TIn): TOut;
}
interface Filter<T> extends Converter<T, boolean> { }

interface IQuery<T> extends IFrom<T> {
    any: IAny<T>;
    all: IAll<T>;
    to: ITo<T>;
    take: ITake<T>;
    skip: ISkip<T>;
}

interface IAny<T> {
    (func: Filter<T>): boolean;
}

interface IAll<T> {
    (func: Filter<T>): boolean;
}

interface ITo<TSource> {
    <T>(func: Converter<TSource, T>): IQuery<T>;
}

interface IFrom<T> {
    (items: T[]): IQuery<T>;
}

interface IFlow<T, TConj> {
    (func: Filter<T>): TConj;
}

interface INot<T, TConj> extends IFlow<T, TConj> {
    not: (func: Filter<T>) => TConj;
}

interface IAction<T, TConj> {
    (count: number): TConj;
    if: IIf<T, TConj>;
    while: IWhile<T, TConj>;
}

interface IConjuction<T, TConj> extends IQuery<T> {
    and: TConj;
    or: TConj;
    then: IQuery<T>;
}

interface IIf<T, TConj> extends INot<T, TConj> { }
interface IWhile<T, TConj> extends INot<T, TConj> { }

interface ITake<T> extends IAction<T, ITaken<T>> { }
interface ISkip<T> extends IAction<T, ISkipped<T>> { }

interface ITaken<T> extends IConjuction<T, ITake<T>> { }
interface ISkipped<T> extends IConjuction<T, ISkip<T>> { }

var from: IQuery<number>;
var items: number[];
var otheritems: number[];
var condition: Filter<number>;
var convert: Converter<number, boolean>;

from(items).any(condition);
from(items).all(condition);
from(items).skip(10).take(5);
from(items).take.if(condition);
from(items).take.if.not(condition);
from(items).take.while(condition);
from(items).take.while.not(condition);
from(items).skip.if(condition);
from(items).skip.if.not(condition);
from(items).skip.while(condition);
from(items).skip.while.not(condition);
from(items).to(convert);
from(items).skip.while.not(condition).to(convert);
from(items).skip.if(condition).and.if.not(condition).take.if(condition).to(convert);

//-------------------------------------------
from(items).skip.if(condition).then.take.if(condition).to(convert);
from(items).skip(10).if(condition);
from(items).skip(10).and.if(condition);
from(items).skip(10).or.if(condition);
from(items).and(otheritems).take.while(condition).to(convert);
from(items).and.from(otheritems).to(convert);
from(items).and.from(otheritems).take.if(condition).to(convert);
from(items).with(otheritems).to(convert);
from(items).mix(otheritems).with(condition).as(combiner);
from(items).mix(otheritems).using(condition).to(convert);
from(items).mix.with(otheritems).using(condition).to(convert);<commit_msg>pairing, mixing, ordering and grouping<commit_after>﻿module Query {
    export interface IConverter<TIn, TOut> { (item: TIn): TOut; }
    export interface IFilter<T> extends IConverter<T, boolean> { }
    export interface ISorter<T> { (a: T, b: T): number; }

    export interface IQuery<T> {
        any: IAny<T>;
        all: IAll<T>;
        as: IAs<T>;
        count: ICount<T>;
        flatten: IFlatten<T>;
        group: IGroup<T>;
        mix: IMix<T>;
        order: IOrder<T>;
        pair: IPair<T>;
        take: ITake<T>;
        skip: ISkip<T>;
        unique: IUnique<T>;
    }

    interface IAny<T> {
        (func?: IFilter<T>): boolean;
    }

    interface IAll<T> {
        (func?: IFilter<T>): boolean;
    }

    interface IAs<TSource> {
        <T>(func?: IConverter<TSource, T>): IQuery<T>;
    }

    interface IConjuction<T, TConj> extends IQuery<T> {
        and: TConj;
        or: TConj;
        then: IQuery<T>;
    }

    interface ICount<T> {
        (func?: IFilter<T>): boolean;
    }

    interface IFlatten<T> {
        (): IQuery<T>;
        <TOut>(func: IConverter<T, TOut[]>): IQuery<TOut>;
        <TOut>(func: IConverter<T, IQuery<TOut>>): IQuery<TOut>;
    }

    interface IFrom {
        <T>(items: T[]): IQuery<T>;
    }

    interface IGroup<T> {
        by: IGroupBy<T>;
    }

    interface IGrouping<TKey, TValue> {
        key: TKey;
        values: IQuery<TValue>;
    }

    interface IGroupBy<T> {
        <TKey, TResult>(func: IConverter<T, TKey>): IQuery<IGrouping<TKey, T>>;
    }

    interface IIf<T, TConj> {
        (func: IFilter<T>): TConj;
        not: INot<T, TConj>;
    }

    interface IMix<T> {
        with: IMixWith<T>;
    }

    interface IMixWith<T> {
        (array: T[]): IQuery<T>;
    }

    interface INot<T, TConj> {
        (func: IFilter<T>): TConj;
    }

    interface IOrder<T> {
        by: IOrderBy<T, IOrdered<T>>;
    }

    interface IOrdered<T> extends IOrder<T> {
        then: IOrder<T>;
    }

    interface IOrderBy<T, TResult> {
        (func: ISorter<T>): TResult;
    }

    interface IPair<T> {
        with: IPairWith<T>;
    }

    interface IPairWith<T> {
        <TTarget, TResult>(array: TTarget[]): IPairQuery<T, TTarget>;
    }

    interface IPairing<TSource, TTarget> {
        source: TSource;
        target: TTarget;
    }

    interface IPairQuery<TSource, TTarget> extends IQuery<IPairing<TSource, TTarget>> {
        if: <TResult>(condition: IFilter<IPairing<TSource, TTarget>>) => IQuery<IPairing<TSource, TTarget>>;
    }

    interface ITake<T> {
        (count: number): IQuery<T>;
        if: IIf<T, ITaken<T>>;
        while: IWhile<T, ITaken<T>>;
    }

    interface ITaken<T> extends IQuery<T> {
        and: ITake<T>;
        or: ITake<T>;
        then: IQuery<T>;
    }

    interface ISkip<T> {
        (count: number): IQuery<T>;
        if: IIf<T, ITaken<T>>;
        while: IWhile<T, ITaken<T>>;
    }

    interface ISkipped<T> extends IQuery<T> {
        and: ISkip<T>;
        or: ISkip<T>;
        then: IQuery<T>;
    }

    interface IUnique<T> {
        (): IQuery<T>;
        by: IUniqueBy<T>;
    }

    interface IUniqueBy<T> {
        <TKey>(func: IConverter<T,TKey>): T;
    }

    interface IWhile<T, TConj> {
        (func: IFilter<T>): TConj;
        not: INot<T, TConj>;
    }

    export var from: IFrom;
}

var items: number[];
var otheritems: number[];
var condition: Query.IFilter<number>;
var convert: Query.IConverter<number, boolean>;
var sort: Query.ISorter<number>;

Query.from(items).any(condition);
Query.from(items).all(condition);
Query.from(items).skip(10).take(5);
Query.from(items).take.if(condition);
Query.from(items).take.if.not(condition);
Query.from(items).take.while(condition);
Query.from(items).take.while.not(condition);
Query.from(items).skip.if(condition);
Query.from(items).skip.if.not(condition);
Query.from(items).skip.while(condition);
Query.from(items).skip.while.not(condition);
Query.from(items).as<boolean>();
Query.from(items).as(convert);
Query.from(items).skip.while.not(condition).as(convert);
Query.from(items).skip.if(condition).and.if.not(condition).take.if(condition).as(convert);
Query.from(items).order.by(sort).then.by(sort);
Query.from(items).group.by(convert).flatten(group => group.values);
Query.from(items).group.by(convert).as(group => group.values).flatten();
Query.from(items).pair.with(otheritems).if(pair => pair.source == pair.target).as(pair => pair.source + pair.target);
Query.from(items).unique.by(convert);
Query.from(items).mix.with(otheritems);

//-------------------------------------------

Query.from(items).skip.if(condition).then.take.if(condition).as(convert);
Query.from(items).skip(10).if(condition);
Query.from(items).skip(10).and.if(condition);
Query.from(items).skip(10).or.if(condition);
Query.from(items).and(otheritems).take.while(condition).as(convert);
Query.from(items).and.from(otheritems).as(convert);
Query.from(items).and.from(otheritems).take.if(condition).as(convert);
Query.from(items).with(otheritems).to(convert);
Query.from(items).mix(otheritems).with(condition).as(convert);
Query.from(items).mix(otheritems).using(condition).as(convert);
Query.from(items).mix.with(otheritems).using(condition).as(convert);
{'fraction_non_alphanumeric': 0.190623390005152, 'fraction_numerical': 0.00231839258114374, 'mean_word_length': 3.5515826494724503, 'pattern_counts': {'":': 0, '<': 169, '<?xml version=': 0, '>': 175, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2811400', 'n_tokens_mistral': 2863, 'n_tokens_neox': 2818, 'n_words': 468}