<commit_before>package org.typemeta.funcj.control;

import org.typemeta.funcj.data.*;
import org.typemeta.funcj.functions.Functions.F;
import org.typemeta.funcj.tuples.Tuple2;

import java.util.Iterator;
import java.util.stream.Stream;

import static org.typemeta.funcj.data.Unit.UNIT;

/**
 * State monad.
 * <p>
 * Each {@code State} instance is a state processor that takes a state of type {@code S},
 * and produces a new state and a result of type {@code A}.
 * The state processor is represented by the {@link StateR#runState(Object)} SAM.
 * <p>
 * Note, this {@code State} type uses recursion and will blow the stack
 * for heavily chained computations.
 * If this is an issue then use {@link State}, which avoids recursion.
 * @param <S>       the state type
 * @param <A>       the result type
 */
@FunctionalInterface
public interface StateR<S, A> {

    /**
     * A construct a {@code State} instance which leaves the input state unchanged and sets the result to a.
     * @param a         the state result value
     * @param <S>       the state type
     * @param <A>       the result type
     * @return          the new {@code State} instance
     */
    static <S, A> StateR<S, A> pure(A a) {
        return st -> Tuple2.of(st, a);
    }

    /**
     * Take a function provided by a {@code State} and apply it to a value in another {@code State}.
     * @param sf        the state that wraps a function type
     * @param sa        the state that wraps the function argument type
     * @param <S>       the state type
     * @param <A>       the function argument type
     * @param <B>       the function return type
     * @return          a new {@code State} instance which contains the result of applying the function
     */
    static <S, A, B> StateR<S, B> ap(StateR<S, F<A, B>> sf, StateR<S, A> sa) {
        return sa.apply(sf);
    }

    /**
     * Construct a {@code State} which sets the state to {@code st} and sets the result to {@link Unit#UNIT}.
     * @param st        the state value
     * @param <S>       the state type
     * @return          the new {@code State} instance
     */
    static <S> StateR<S, Unit> put(S st) {
        return u -> Tuple2.of(st, UNIT);
    }

    /**
     * Construct a {@code State} which leaves the state value unchanged and sets the result to the supplied value.
     * @param <S>       the state type
     * @return          the new {@code State} instance
     */
    static <S> StateR<S, S> get() {
        return s -> Tuple2.of(s, s);
    }

    /**
     * Construct a {@code State} which applies a function to the state,
     * and sets the result to {@link Unit#UNIT}.
     * @param f         the function
     * @param <S>       the state type
     * @return          the new {@code State} instance
     */
    static <S> StateR<S, Unit> modify(F<S, S> f) {
        return StateR.<S>get().flatMap(x ->
            put(f.apply(x))
        );
    }

    /**
     * A state which leaves the state unchanged,
     * and sets the result to the function f applied to the state.
     * @param f         the function
     * @param <S>       the state type
     * @param <A>       the result type
     * @return          the new {@code State} instance
     */
    static <S, A> StateR<S, A> inspect(F<S, A> f) {
        return StateR.<S>get().map(f);
    }

    /**
     * A state which leaves the state unchanged,
     * and sets the result to the function f applied to the state.
     * @param f         the function
     * @param <S>       the state type
     * @param <A>       the result type
     * @return          the new {@code State} instance
     */
    static <S, A> StateR<S, A> gets(F<S, A> f) {
        return StateR.<S>get().map(f);
    }

    /**
     * Standard applicative traversal.
     * @param lt        list of values
     * @param f         function to be applied to each value in the list
     * @param <S>       the state type
     * @param <A>       type of list elements
     * @param <B>       the state result type
     * @return          a {@code State} which wraps an {@link IList} of values
     */
    static <S, A, B> StateR<S, IList<B>> traverse(IList<A> lt, F<A, StateR<S, B>> f) {
        return lt.foldRight(
            (a, slb) -> f.apply(a).apply(slb.map(l -> l::add)),
            pure(IList.nil())
        );
    }

    /**
     * Standard applicative sequencing.
     * @param lsa       the list of {@code State} values
     * @param <S>       the state type
     * @param <A>       the state result type
     * @return          a {@code State} which wraps an {@link IList} of values
     */
    static <S, A> StateR<S, IList<A>> sequence(IList<? extends StateR<S, A>> lsa) {
        return lsa.foldRight(
            (sa, sla) -> sa.apply(sla.map(l -> l::add)),
            pure(IList.nil())
        );
    }

    /**
     * Variation of {@link StateR#sequence(IList)} for {@link Stream}.
     * @param sst       the stream of {@code StateR} values
     * @param <S>       the state type
     * @param <T>       the result type of the {@code StateR}s in the stream
     * @return          a {@code StateR} which wraps an {@link Stream} of values
     */
    static <S, T> StateR<S, Stream<T>> sequence(Stream<StateR<S, T>> sst) {
        final Iterator<StateR<S, T>> iter = sst.iterator();
        StateR<S, IList<T>> slt = pure(IList.nil());
        while (iter.hasNext()) {
            final StateR<S, T> st = iter.next();
            slt = st.apply(slt.map(lt -> lt::add));
        }
        return slt.map(IList::stream);
    }

    /**
     * Repeatedly call the function {@code f} until it returns {@code Either.Right}.
     * <p>
     * Call the function {@code f} and if it returns a right value then return the wrapped value,
     * otherwise extract the value and call {@code f} again.
     * @param a         the starting value
     * @param f         the function
     * @param <S>       the state type
     * @param <A>       the starting value type
     * @param <B>       the final value type
     * @return          the final value
     */
    static <S, A, B> StateR<S, B> tailRecM(A a, F<A, StateR<S, Either<A, B>>> f) {
        return st -> {
            A aa = a;
            S s = st;
            while (true) {
                final Tuple2<S, Either<A, B>> t2e = f.apply(aa).runState(s);

                if (t2e._2 instanceof Either.Left) {
                    final Either.Left<A, B> left = (Either.Left<A, B>) t2e._2;
                    aa = left.value;
                    s = t2e._1;
                } else {
                    final Either.Right<A, B> right = (Either.Right<A, B>) t2e._2;
                    return Tuple2.of(t2e._1, right.value);
                }
            }
        };
    }

    /**
     * {@code Kleisli} models composable operations that return a {@code StateR}.
     * @param <S>       the state type
     * @param <A>       the input type
     * @param <B>       the value type of the returned @{code StateR} type
     */
    @FunctionalInterface
    interface Kleisli<S, A, B> {
        /**
         * Construct a {@code Kleisli} value from a function.
         * @param f         the function
         * @param <S>       the state type
         * @param <T>       the input type
         * @param <U>       the value type of the returned @{code State} value
         * @return          the new {@code Kleisli}
         */
        static <S, T, U> Kleisli<S, T, U> of(F<T, StateR<S, U>> f) {
            return f::apply;
        }

        /**
         * Apply this {@code Kleisli} operation
         * @param a         the input value
         * @return          the result of the operation
         */
        StateR<S, B> apply(A a);

        /**
         * Compose this {@code Kleisli} with another by applying this one first,
         * then the other.
         * @param kUV       the {@code Kleisli} to be applied after this one
         * @param <C>       the second {@code Kleisli}'s return type
         * @return          the composed {@code Kleisli}
         */
        default <C> Kleisli<S, A, C> andThen(Kleisli<S, B, C> kUV) {
            return a -> apply(a).flatMap(kUV::apply);
        }

        /**
         * Compose this {@code Kleisli} with another by applying the other one first,
         * and then this one.
         * @param kST       the {@code Kleisli} to be applied after this one
         * @param <C>       the first {@code Kleisli}'s input type
         * @return          the composed {@code Kleisli}<commit_msg>Update StateR.java<commit_after>package org.typemeta.funcj.control;

import org.typemeta.funcj.data.*;
import org.typemeta.funcj.functions.Functions.F;
import org.typemeta.funcj.tuples.Tuple2;

import java.util.Iterator;
import java.util.stream.Stream;

import static org.typemeta.funcj.data.Unit.UNIT;

/**
 * State monad.
 * <p>
 * Each {@code State} instance is a state processor that takes a state of type {@code S},
 * and produces a new state and a result of type {@code A}.
 * The state processor is represented by the {@link StateR#runState(Object)} SAM.
 * <p>
 * Note, this {@code State} type uses recursion and will blow the stack
 * for heavily chained computations.
 * If this is an issue then use {@link State}, which avoids recursion.
 * @param <S>       the state type
 * @param <A>       the result type
 */
@FunctionalInterface
public interface StateR<S, A> {

    /**
     * A construct a {@code State} instance which leaves the input state unchanged and sets the result to a.
     * @param a         the state result value
     * @param <S>       the state type
     * @param <A>       the result type
     * @return          the new {@code State} instance
     */
    static <S, A> StateR<S, A> pure(A a) {
        return st -> Tuple2.of(st, a);
    }

    /**
     * Take a function provided by a {@code State} and apply it to a value in another {@code State}.
     * @param sf        the state that wraps a function type
     * @param sa        the state that wraps the function argument type
     * @param <S>       the state type
     * @param <A>       the function argument type
     * @param <B>       the function return type
     * @return          a new {@code State} instance which contains the result of applying the function
     */
    static <S, A, B> StateR<S, B> ap(StateR<S, F<A, B>> sf, StateR<S, A> sa) {
        return sa.apply(sf);
    }

    /**
     * Construct a {@code State} which sets the state to {@code st} and sets the result to {@link Unit#UNIT}.
     * @param st        the state value
     * @param <S>       the state type
     * @return          the new {@code State} instance
     */
    static <S> StateR<S, Unit> put(S st) {
        return u -> Tuple2.of(st, UNIT);
    }

    /**
     * Construct a {@code State} which leaves the state value unchanged and sets the result to the supplied value.
     * @param <S>       the state type
     * @return          the new {@code State} instance
     */
    static <S> StateR<S, S> get() {
        return s -> Tuple2.of(s, s);
    }

    /**
     * Construct a {@code State} which applies a function to the state,
     * and sets the result to {@link Unit#UNIT}.
     * @param f         the function
     * @param <S>       the state type
     * @return          the new {@code State} instance
     */
    static <S> StateR<S, Unit> modify(F<S, S> f) {
        return StateR.<S>get().flatMap(x ->
            put(f.apply(x))
        );
    }

    /**
     * A state which leaves the state unchanged,
     * and sets the result to the function f applied to the state.
     * @param f         the function
     * @param <S>       the state type
     * @param <A>       the result type
     * @return          the new {@code State} instance
     */
    static <S, A> StateR<S, A> inspect(F<S, A> f) {
        return StateR.<S>get().map(f);
    }

    /**
     * A state which leaves the state unchanged,
     * and sets the result to the function f applied to the state.
     * @param f         the function
     * @param <S>       the state type
     * @param <A>       the result type
     * @return          the new {@code State} instance
     */
    static <S, A> StateR<S, A> gets(F<S, A> f) {
        return StateR.<S>get().map(f);
    }

    /**
     * Standard applicative traversal.
     * @param lt        list of values
     * @param f         function to be applied to each value in the list
     * @param <S>       the state type
     * @param <A>       type of list elements
     * @param <B>       the state result type
     * @return          a {@code State} which wraps an {@link IList} of values
     */
    static <S, A, B> StateR<S, IList<B>> traverse(IList<A> lt, F<A, StateR<S, B>> f) {
        return lt.foldRight(
            (a, slb) -> f.apply(a).apply(slb.map(l -> l::add)),
            pure(IList.nil())
        );
    }

    /**
     * Standard applicative sequencing.
     * @param lsa       the list of {@code State} values
     * @param <S>       the state type
     * @param <A>       the state result type
     * @return          a {@code State} which wraps an {@link IList} of values
     */
    static <S, A> StateR<S, IList<A>> sequence(IList<? extends StateR<S, A>> lsa) {
        return lsa.foldRight(
            (sa, sla) -> sa.apply(sla.map(l -> l::add)),
            pure(IList.nil())
        );
    }

    /**
     * Variation of {@link StateR#sequence(IList)} for {@link Stream}.
     * @param sst       the stream of {@code StateR} values
     * @param <S>       the state type
     * @param <T>       the result type of the {@code StateR}s in the stream
     * @return          a {@code StateR} which wraps an {@link Stream} of values
     */
    static <S, T> StateR<S, Stream<T>> sequence(Stream<StateR<S, T>> sst) {
        final Iterator<StateR<S, T>> iter = sst.iterator();
        StateR<S, IList<T>> slt = pure(IList.nil());
        while (iter.hasNext()) {
            final StateR<S, T> st = iter.next();
            slt = st.apply(slt.map(lt -> lt::add));
        }
        return slt.map(IList::stream);
    }

    /**
     * Repeatedly call the function {@code f} until it returns {@code Either.Right}.
     * <p>
     * Call the function {@code f} and if it returns a right value then return the wrapped value,
     * otherwise extract the value and call {@code f} again.
     * @param a         the starting value
     * @param f         the function
     * @param <S>       the state type
     * @param <A>       the starting value type
     * @param <B>       the final value type
     * @return          the final value
     */
    static <S, A, B> StateR<S, B> tailRecM(A a, F<A, StateR<S, Either<A, B>>> f) {
        return st -> {
            A aa = a;
            S s = st;
            while (true) {
                final Tuple2<S, Either<A, B>> t2e = f.apply(aa).runState(s);

                if (t2e._2 instanceof Either.Left) {
                    final Either.Left<A, B> left = (Either.Left<A, B>) t2e._2;
                    aa = left.value;
                    s = t2e._1;
                } else {
                    final Either.Right<A, B> right = (Either.Right<A, B>) t2e._2;
                    return Tuple2.of(t2e._1, right.value);
                }
            }
        };
    }

    /**
     * {@code Kleisli} models composable operations that return a {@code StateR}.
     * @param <S>       the state type
     * @param <A>       the input type
     * @param <B>       the value type of the returned {@code StateR} type
     */
    @FunctionalInterface
    interface Kleisli<S, A, B> {
        /**
         * Construct a {@code Kleisli} value from a function.
         * @param f         the function
         * @param <S>       the state type
         * @param <T>       the input type
         * @param <U>       the value type of the returned {@code State} value
         * @return          the new {@code Kleisli}
         */
        static <S, T, U> Kleisli<S, T, U> of(F<T, StateR<S, U>> f) {
            return f::apply;
        }

        /**
         * Apply this {@code Kleisli} operation
         * @param a         the input value
         * @return          the result of the operation
         */
        StateR<S, B> apply(A a);

        /**
         * Compose this {@code Kleisli} with another by applying this one first,
         * then the other.
         * @param kUV       the {@code Kleisli} to be applied after this one
         * @param <C>       the second {@code Kleisli}'s return type
         * @return          the composed {@code Kleisli}
         */
        default <C> Kleisli<S, A, C> andThen(Kleisli<S, B, C> kUV) {
            return a -> apply(a).flatMap(kUV::apply);
        }

        /**
         * Compose this {@code Kleisli} with another by applying the other one first,
         * and then this one.
         * @param kST       the {@code Kleisli} to be applied after this one
         * @param <C>       the first {@code Kleisli}'s input type
         * @return          the composed {@code Kleisli}
{'fraction_non_alphanumeric': 0.11920257988859571, 'fraction_numerical': 0.001993550278510701, 'mean_word_length': 1.7882949158084027, 'pattern_counts': {'":': 0, '<': 203, '<?xml version=': 0, '>': 225, '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': '2011189', 'n_tokens_mistral': 5277, 'n_tokens_neox': 5179, 'n_words': 1932}