/// <summary> /// Maps the elements in a container <typeparamref name="S"/> to an value which has an associated monoid <typeparamref name="TMonoid"/> and uses the monoid-logic to combine the results. /// Also known as <em>foldMapOf</em>. /// </summary> /// <typeparam name="S">The type of the input structure.</typeparam> /// <typeparam name="A">The type of the elements.</typeparam> /// <typeparam name="TResult">The type of the monoidal result.</typeparam> /// <typeparam name="TMonoid">The type of the monoid.</typeparam> /// <param name="lens">The fold to run.</param> /// <param name="f">The function to map each element to a monoid.</param> /// <param name="input">The input structure.</param> public static TResult Fold <S, A, TResult, TMonoid>(IFold <S, A> lens, Func <A, TResult> f, S input) where TMonoid : IMonoid <TResult> => lens.FoldFunc <Const <TMonoid, TResult, A>, Const <TMonoid, TResult, S> >()(f.Then(x => new Const <TMonoid, TResult, A>(x)))(input).RealValue;
/// <summary> /// Folds the elements of a container using <paramref name="f"/> as the combining-function and <paramref name="acc"/> as the initial accumulator. /// Also known as <em>foldrOf</em>. /// </summary> /// <typeparam name="S">The type of the input structure.</typeparam> /// <typeparam name="A">The type of the elements.</typeparam> /// <typeparam name="TResult">The type of the monoidal result.</typeparam> /// <param name="lens">The fold to run.</param> /// <param name="f">The function to combine two elements.</param> /// <param name="acc">The initial accumulator value.</param> /// <param name="input">The input structure.</param> public static TResult Fold <S, A, TResult>(IFold <S, A> lens, Func <A, TResult, TResult> f, TResult acc, S input) => lens.FoldFunc <Const <Monoid.EndoMonoid <TResult>, Func <TResult, TResult>, A>, Const <Monoid.EndoMonoid <TResult>, Func <TResult, TResult>, S> >()(a => new Const <Monoid.EndoMonoid <TResult>, Func <TResult, TResult>, A>(x => f(a, x)))(input).RealValue(acc);
/// <summary> /// Turns the element(s) retrieved by an <see cref="IGetter{S, A}"/> into a list. /// </summary> /// <typeparam name="S">The type of the input structure.</typeparam> /// <typeparam name="A">The type of the part to get.</typeparam> /// <param name="lens">The getter.</param> /// <param name="input">The input structure.</param> public static IFuncList <A> ToList <S, A>(this IFold <S, A> lens, S input) => Fold(lens, (x, xs) => { xs.Push(x); return(xs); }, new Stack <A>(), input).MakeFuncList();
public IFold <S, C> ComposeWith <C>(IFold <A, C> other) => _fold.ComposeWith(other);
public Traversal(IFold <S, A> fold, ISetter <S, T, A, B> setter) { _fold = fold; _setter = setter; }
/// <summary> /// Composes two folds. The second folds drills further into the result of the first. /// </summary> /// <typeparam name="S">The type of the outer container.</typeparam> /// <typeparam name="AOuter">The type of the outer value.</typeparam> /// <typeparam name="AInner">The type of the inner outer value/inner container.</typeparam> /// <param name="lens">The outer setter.</param> /// <param name="then">The inner setter.</param> public static IFold <S, AInner> Then <S, AOuter, AInner>(this IFold <S, AOuter> lens, IFold <AOuter, AInner> then) { return(new Fold <S, AInner>(t => lens.FoldFunc(t).After(then.FoldFunc(t)))); }