Category Theory via C# (6) Monoidal Functor and Applicative Functor

[LINQ via C#] - [Category Theory]

Monoidal functor

Given monoidal categories (C, ⊗, IC) and (D, ⊛, ID), a strong lax monoidal functor is a functor F: C → D equipped with:

  • Monoid binary multiplication operation, which is a natural transformation φ: F(X) ⊛ F(Y) ⇒ F(X ⊗ Y)
  • Monoid unit, which is a morphism ι: ID → F(IC)

F preserves the monoid laws in D:

  • Associativity law is preserved with D’s associator αD:
    Untitled-4.fw_thumb1
  • Left unit law is preserved with D’s left unitor λD:
    image_thumb 
    and right unit law is preserved with D’s right unitor ρD:
    Untitled-3..fw_thumb 

In this tutorial, strong lax monoidal functor is called monoidal functor for short. In DotNet category, monoidal functors are monoidal endofunctors. In the definition, (C, ⊗, IC) and (D, ⊛, ID) are both (DotNet, ValueTuple<,>, Unit), so monoidal functor can be IEnumerable<T1>, IEnumerable<T2>defined as:

public interface IMonoidalFunctor<TMonoidalFunctor<>> : IFunctor<TMonoidalFunctor<>>
    where TMonoidalFunctor : IMonoidalFunctor<TMonoidalFunctor<>>
{
    // From IFunctor<TMonoidalFunctor<>>:
    // Select: (TSource -> TResult) -> (TMonoidalFunctor<TSource> -> TMonoidalFunctor<TResult>)
    // Func<TMonoidalFunctor<TSource>, TMonoidalFunctor<TResult>> Select<TSource, TResult>(Func<TSource, TResult> selector);
// Multiply: TMonoidalFunctor&lt;T1&gt; x TMonoidalFunctor&lt;T2&gt; -&gt; TMonoidalFunctor&lt;T1 x T2&gt;
// Multiply: ValueTuple&lt;TMonoidalFunctor&lt;T1&gt;, TMonoidalFunctor&lt;T2&gt;&gt; -&gt; TMonoidalFunctor&lt;ValueTuple&lt;T1, T2&gt;&gt;
<span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">ValueTuple</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T1</span><span style="color: black;">, </span><span style="color: #2b91af;">T2</span><span style="color: black;">&gt;&gt; Multiply&lt;</span><span style="color: #2b91af;">T1</span><span style="color: black;">, </span><span style="color: #2b91af;">T2</span><span style="color: black;">&gt;(
    <span style="color: black;"></span><span style="color: #2b91af;">ValueTuple</span></span><span style="color: #2b91af;"></span><span style="color: black;">&lt;<span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span>&lt;</span><span style="color: #2b91af;">T1</span><span style="color: black;">&gt;, <span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span>&lt;</span><span style="color: #2b91af;">T2</span><span style="color: black;">&gt;&gt; bifunctor);

</span><span style="color: green;">// Unit: Unit -&gt; TMonoidalFunctor&lt;Unit&gt;
<span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit);

}

Multiply accepts a ValueTuple<IEnumerable<T1>, IEnumerable<T2>> bifunctor, which is literally a 2-tuple (IEnumerable<T1>, IEnumerable<T2>). For convenience, the explicit ValueTuple<,> parameter can be represented by an implicit tuple, a pair of parameters. So the monoidal functor definition is equivalent to:

public interface IMonoidalFunctor<TMonoidalFunctor<>> : IFunctor<TMonoidalFunctor<>>
    where TMonoidalFunctor : IMonoidalFunctor<TMonoidalFunctor<>>
{
    // Multiply: TMonoidalFunctor<T1> x TMonoidalFunctor<T2> -> TMonoidalFunctor<T1 x T2>
    // Multiply: (TMonoidalFunctor<T1>, TMonoidalFunctor<T2>) -> TMonoidalFunctor<(T1, T2)>
    TMonoidalFunctor<(T1, T2)> Multiply<T1, T2>(
        TMonoidalFunctor<T1> source1, TMonoidalFunctor<T2>> source2); // Unit: Unit
</span><span style="color: green;">// Unit: Unit -&gt; TMonoidalFunctor&lt;Unit&gt;
<span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit);

}

IEnumerable<> monoidal functor

IEnumerable<> functor is a monoidal functor. Its Multiply method can be implemented as its extension method:

public static partial class EnumerableExtensions // IEnumerable<T> : IMonoidalFunctor<IEnumerable<>>
{
    // Multiply: IEnumerable<T1> x IEnumerable<T2> -> IEnumerable<T1 x T2>
    // Multiply: ValueTuple<IEnumerable<T1>, IEnumerable<T2>> -> IEnumerable<ValueTuple<T1, T2>>
    // Multiply: (IEnumerable<T1>, IEnumerable<T2>) -> IEnumerable<(T1, T2)>
    public static IEnumerable<(T1, T2)> Multiply<T1, T2>(
        this IEnumerable<T1> source1, IEnumerable<T2> source2) // Implicit tuple.
    {
        foreach (T1 value1 in source1)
        {
            foreach (T2 value2 in source2)
            {
                yield return (value1, value2);
            }
        }
    }
</span><span style="color: green;">// Unit: Unit -&gt; IEnumerable&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">IEnumerable</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">)
{
    </span><span style="color: blue;">yield return </span><span style="color: black;">unit;
}

}

Now extension method Multiply can be used as a infix operator. It can be verified that the above Multiply and Unit implementations preserve the monoid laws by working with associator, left unitor and right unitor of DotNet monoidal category:

// using static Dixin.Linq.CategoryTheory.DotNetCategory;
internal static void MonoidalFunctorLaws()
{
    IEnumerable<Unit> unit = Unit();
    IEnumerable<int> source1 = new int[] { 0, 1 };
    IEnumerable<char> source2 = new char[] { '@', '#' };
    IEnumerable<bool> source3 = new bool[] { true, false };
    IEnumerable<int> source = new int[] { 0, 1, 2, 3, 4 };
</span><span style="color: green;">// Associativity preservation: source1.Multiply(source2).Multiply(source3).Select(Associator) == source1.Multiply(source2.Multiply(source3)).
</span><span style="color: black;">source1.Multiply(source2).Multiply(source3).Select(Associator).WriteLines();
    </span><span style="color: green;">// (0, (@, True)) (0, (@, False)) (0, (#, True)) (0, (#, False))
    // (1, (@, True)) (1, (@, False)) (1, (#, True)) (1, (#, False))
</span><span style="color: black;">source1.Multiply(source2.Multiply(source3)).WriteLines();
    </span><span style="color: green;">// (0, (@, True)) (0, (@, False)) (0, (#, True)) (0, (#, False))
    // (1, (@, True)) (1, (@, False)) (1, (#, True)) (1, (#, False))
// Left unit preservation: unit.Multiply(source).Select(LeftUnitor) == source.
</span><span style="color: black;">unit.Multiply(source).Select(LeftUnitor).WriteLines(); </span><span style="color: green;">// 0 1 2 3 4
// Right unit preservation: source == source.Multiply(unit).Select(RightUnitor).
</span><span style="color: black;">source.Multiply(unit).Select(RightUnitor).WriteLines(); </span><span style="color: green;">// 0 1 2 3 4

}

How could these methods be useful? Remember functor’s Select method enables selector working with value(s) wrapped by functor:

internal static void Selector1Arity(IEnumerable<int> xs)
{
    Func<int, bool> selector = x => x > 0;
    // Apply selector with xs.
    IEnumerable<bool> applyWithXs = xs.Select(selector);
}

So Select can be viewed as applying 1 arity selector (a TSource –> TResult function) with TFunctor<TSource>. For a N arity selector, to have it work with value(s) wrapped by functor, first curry it, so that it can be viewed as 1 arity function. In the following example, the (T1, T2, T3) –> TResult selector is curried to T1 –> (T2 –> T3 –> TResult) function, so that it can be viewed as only have 1 parameter, and can work with TFunctor<T1>:

internal static void SelectorNArity(IEnumerable<int> xs, IEnumerable<long> ys, IEnumerable<double> zs)
{
    Func<int, long, double, bool> selector = (x, y, z) => x + y + z > 0;
</span><span style="color: green;">// Curry selector.
</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">long</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">double</span><span style="color: black;">, </span><span style="color: blue;">bool</span><span style="color: black;">&gt;&gt;&gt; curriedSelector = 
    selector.Curry(); </span><span style="color: green;">// 1 arity: x =&gt; (y =&gt; z =&gt; x + y + z &gt; 0)
// Partially apply selector with xs.
</span><span style="color: #2b91af;">IEnumerable</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">long</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">double</span><span style="color: black;">, </span><span style="color: blue;">bool</span><span style="color: black;">&gt;&gt;&gt; applyWithXs = xs.Select(curriedSelector);</span></pre>

So partially applying the T1 –> (T2 –> T3 –> TResult) selector with TFunctor<T1> returns TFunctor<T2 –> T3 –> TResult>, where the T2 –> T3 –> TResult function is wrapped by the TFunctor<> functor. To further apply TFunctor<T2 –> T3 –> TResult> with TFunctor<T2>, Multiply can be called:

    // Partially apply selector with ys.
    IEnumerable<(Func<long, Func<double, bool>>, long)> multiplyWithYs = applyWithXs.Multiply(ys);
    IEnumerable<Func<double, bool>> applyWithYs = multiplyWithYs.Select(product =>
    {
        Func<long, Func<double, bool>> partialAppliedSelector = product.Item1;
        long y = product.Item2;
        return partialAppliedSelector(y);
    });

The result of Multiply is TFunctor<(T2 –> T3 –> TResult, T2)>, where each T2 –> T3 –> TResult function is paired with each T2 value, so that each function can be applied with each value, And TFunctor<(T2 –> T3 –> TResult, T2)> is mapped to TFunctor<(T3 –> TResult)>, which can be applied with TFunctor<T3> in the same way:

    // Partially apply selector with zs.
    IEnumerable<(Func<double, bool>, double)> multiplyWithZs = applyWithYs.Multiply(zs);
    IEnumerable<bool> applyWithZs = multiplyWithZs.Select(product =>
    {
        Func<double, bool> partialAppliedSelector = product.Item1;
        double z = product.Item2;
        return partialAppliedSelector(z);
    });
}

So Multiply enables applying functor-wrapped functions (TFunctor<T –> TResult>) with functor-wrapped values (TFunctor<TSource>), which returns functor-wrapped results (TFunctor<TResult>). Generally, the Multiply and Select calls can be encapsulated as the following Apply method:

// Apply: (IEnumerable<TSource -> TResult>, IEnumerable<TSource>) -> IEnumerable<TResult>
public static IEnumerable<TResult> Apply<TSource, TResult>(
    this IEnumerable<Func<TSource, TResult>> selectorWrapper, IEnumerable<TSource> source) =>
        selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));

So that the above N arity selector application becomes:

internal static void Apply(IEnumerable<int> xs, IEnumerable<long> ys, IEnumerable<double> zs)
{
    Func<int, long, double, bool> selector = (x, y, z) => x + y + z > 0;
    // Partially apply selector with xs.
    IEnumerable<Func<long, Func<double, bool>>> applyWithXs = xs.Select(selector.Curry());
    // Partially apply selector with ys.
    IEnumerable<Func<double, bool>> applyWithYs = applyWithXs.Apply(ys);
    // Partially apply selector with zs.
    IEnumerable<bool> applyWithZs = applyWithYs.Apply(zs);
}

Applicative functor

A functor, with the above ability to apply functor-wrapped functions with functor-wrapped values, is also called applicative functor. The following is the definition of applicative functor:

// Cannot be compiled.
public interface IApplicativeFunctor<TApplicativeFunctor<>> : IFunctor<TApplicativeFunctor<>>
    where TApplicativeFunctor<> : IApplicativeFunctor<TApplicativeFunctor<>>
{
    // From: IFunctor<TApplicativeFunctor<>>:
    // Select: (TSource -> TResult) -> (TApplicativeFunctor<TSource> -> TApplicativeFunctor<TResult>)
    // Func<TApplicativeFunctor<TSource>, TApplicativeFunctor<TResult>> Select<TSource, TResult>(Func<TSource, TResult> selector);
// Apply: (TApplicativeFunctor&lt;TSource -&gt; TResult&gt;, TApplicativeFunctor&lt;TSource&gt; -&gt; TApplicativeFunctor&lt;TResult&gt;
<span style="color: black;"></span><span style="color: #2b91af;">TApplicativeFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TResult</span><span style="color: black;">&gt; Apply&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">, </span><span style="color: #2b91af;">TResult</span><span style="color: black;">&gt;(
    <span style="color: black;"></span><span style="color: #2b91af;">TApplicativeFunctor</span>&lt;<span style="color: black;"></span><span style="color: #2b91af;">Func</span>&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">, </span><span style="color: #2b91af;">TResult</span><span style="color: black;">&gt;&gt; selectorWrapper, <span style="color: black;"></span><span style="color: #2b91af;">TApplicativeFunctor</span>&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt; source);

</span><span style="color: green;">// Wrap: TSource -&gt; TApplicativeFunctor&lt;TSource&gt;
<span style="color: black;"></span><span style="color: #2b91af;">TApplicativeFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt; Wrap&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;(</span><span style="color: #2b91af;">TSource </span><span style="color: black;">value);

}

And applicative functor must satisfy the applicative laws:

  • Functor preservation: applying function is equivalent to applying functor-wrapped function
  • Identity preservation: applying functor-wrapped identity function, is equivalent to doing nothing.
  • Composition preservation: functor-wrapped functions can be composed by applying.
  • Homomorphism: applying functor-wrapped function with functor-wrapped value, is equivalent to functor-wrapping the result of applying that function with that value.
  • Interchange: when applying functor-wrapped functions with a functor-wrapped value, the functor-wrapped functions and the functor-wrapped value can interchange position.

IEnumerable<> applicative functor

IEnumerable<> functor is a applicative functor. Again, these methods are implemented as extension methods. And for IEnumerable<>, the Wrap method is called Enumerable to be intuitive:

public static partial class EnumerableExtensions // IEnumerable<T> : IApplicativeFunctor<IEnumerable<>>
{
    // Apply: (IEnumerable<TSource -> TResult>, IEnumerable<TSource>) -> IEnumerable<TResult>
    public static IEnumerable<TResult> Apply<TSource, TResult>(
        this IEnumerable<Func<TSource, TResult>> selectorWrapper, IEnumerable<TSource> source)
    {
        foreach (Func<TSource, TResult> selector in selectorWrapper)
        {
            foreach (TSource value in source)
            {
                yield return selector(value);
            }
        }
    }
</span><span style="color: green;">// Wrap: TSource -&gt; IEnumerable&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">IEnumerable</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt; Enumerable&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">TSource </span><span style="color: black;">value)
{
    </span><span style="color: blue;">yield return </span><span style="color: black;">value;
}

}

It can be verified that the above Apply and Wrap (Enumerable) implementations satisfy the applicative laws:

internal static void ApplicativeLaws()
{
    IEnumerable<int> source = new int[] { 0, 1, 2, 3, 4 };
    Func<int, double> selector = int32 => Math.Sqrt(int32);
    IEnumerable<Func<int, double>> selectorWrapper1 =
        new Func<int, double>[] { int32 => int32 / 2D, int32 => Math.Sqrt(int32) };
    IEnumerable<Func<double, string>> selectorWrapper2 =
        new Func<double, string>[] { @double => @double.ToString("0.0"), @double => @double.ToString("0.00") };
    Func<Func<double, string>, Func<Func<int, double>, Func<int, string>>> o =
        new Func<Func<double, string>, Func<int, double>, Func<int, string>>(Linq.FuncExtensions.o).Curry();
    int value = 5;
</span><span style="color: green;">// Functor preservation: source.Select(selector) == selector.Wrap().Apply(source).
</span><span style="color: black;">source.Select(selector).WriteLines(); </span><span style="color: green;">// 0 1 1.4142135623731 1.73205080756888 2
</span><span style="color: black;">selector.Enumerable().Apply(source).WriteLines(); </span><span style="color: green;">// 0 1 1.4142135623731 1.73205080756888 2
// Identity preservation: Id.Wrap().Apply(source) == source.
</span><span style="color: blue;">new </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">int</span><span style="color: black;">&gt;(</span><span style="color: #2b91af;">Functions</span><span style="color: black;">.Id).Enumerable().Apply(source).WriteLines(); </span><span style="color: green;">// 0 1 2 3 4
// Composition preservation: o.Wrap().Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source) == selectorWrapper2.Apply(selectorWrapper1.Apply(source)).
</span><span style="color: black;">o.Enumerable().Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source).WriteLines();
    </span><span style="color: green;">// 0.0  0.5  1.0  1.5  2.0
    // 0.0  1.0  1.4  1.7  2.0 
    // 0.00 0.50 1.00 1.50 2.00
    // 0.00 1.00 1.41 1.73 2.00
</span><span style="color: black;">selectorWrapper2.Apply(selectorWrapper1.Apply(source)).WriteLines();
    </span><span style="color: green;">// 0.0  0.5  1.0  1.5  2.0
    // 0.0  1.0  1.4  1.7  2.0 
    // 0.00 0.50 1.00 1.50 2.00
    // 0.00 1.00 1.41 1.73 2.00
// Homomorphism: selector.Wrap().Apply(value.Wrap()) == selector(value).Wrap().
</span><span style="color: black;">selector.Enumerable().Apply(value.Enumerable()).WriteLines(); </span><span style="color: green;">// 2.23606797749979
</span><span style="color: black;">selector(value).Enumerable().WriteLines(); </span><span style="color: green;">// 2.23606797749979
// Interchange: selectorWrapper.Apply(value.Wrap()) == (selector =&gt; selector(value)).Wrap().Apply(selectorWrapper).
</span><span style="color: black;">selectorWrapper1.Apply(value.Enumerable()).WriteLines(); </span><span style="color: green;">// 2.5 2.23606797749979
</span><span style="color: blue;">new </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;, </span><span style="color: blue;">double</span><span style="color: black;">&gt;(function =&gt; function(value)).Enumerable().Apply(selectorWrapper1)
    .WriteLines(); </span><span style="color: green;">// 2.5 2.23606797749979

}

Monoidal functor vs. applicative functor

The applicative functor definition is actually equivalent to above monoidal functor definition. First, applicative functor’s Apply and Wrap methods can be implemented by monoidal functor’s Multiply and Unit methods:

public static partial class EnumerableExtensions // IEnumerable<T> : IApplicativeFunctor<IEnumerable<>>
{
    // Apply: (IEnumerable<TSource -> TResult>, IEnumerable<TSource>) -> IEnumerable<TResult>
    public static IEnumerable<TResult> Apply<TSource, TResult>(
        this IEnumerable<Func<TSource, TResult>> selectorWrapper, IEnumerable<TSource> source) =>
            selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));
</span><span style="color: green;">// Wrap: TSource -&gt; IEnumerable&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">IEnumerable</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt; Enumerable&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">TSource </span><span style="color: black;">value) =&gt; Unit().Select(unit =&gt; value);

}

On the other hand, monoidal functor’s Multiply and Unit methods can be implemented by applicative functor’s Apply and Wrap methods:

public static partial class EnumerableExtensions // IEnumerable<T> : IMonoidalFunctor<IEnumerable<>>
{
    // Multiply: IEnumerable<T1> x IEnumerable<T2> -> IEnumerable<T1 x T2>
    // Multiply: (IEnumerable<T1>, IEnumerable<T2>) -> IEnumerable<(T1, T2)>
    public static IEnumerable<(T1, T2)> Multiply<T1, T2>(
        this IEnumerable<T1> source1, IEnumerable<T2> source2) =>
            new Func<T1, T2, (T1, T2)>(ValueTuple.Create).Curry().Enumerable().Apply(source1).Apply(source2);
</span><span style="color: green;">// Unit: Unit -&gt; IEnumerable&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">IEnumerable</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; unit.Enumerable();

}

Generally, for any applicative functor, its (Apply, Wrap) method pair can implement the (Multiply, Unit) method pair required as monoidal functor, and vice versa. This can be virtually demonstrated as:

// Cannot be compiled.
public static class MonoidalFunctorExtensions // (Multiply, Unit) implements (Apply, Wrap).
{
    // Apply: (TMonoidalFunctor<TSource -> TResult>, TMonoidalFunctor<TSource>) -> TMonoidalFunctor<TResult>
    public static TMonoidalFunctor<TResult> Apply<TMonoidalFunctor<>, TSource, TResult>(
        this TMonoidalFunctor<Func<TSource, TResult>> selectorWrapper, TMonoidalFunctor<TSource> source) 
        where TMonoidalFunctor<> : IMonoidalFunctor<TMonoidalFunctor<>> =>
            selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));
</span><span style="color: green;">// Wrap: TSource -&gt; TMonoidalFunctor&lt;TSource&gt;
</span><span style="color: blue;">public static <span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt; Wrap&lt;</span><span style="color: #2b91af;">TMonoidalFunctor</span><span style="color: black;">&lt;&gt;, </span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">TSource </span><span style="color: black;">value) 
    </span><span style="color: blue;">where </span><span style="color: #2b91af;">TMonoidalFunctor</span><span style="color: black;">&lt;&gt; : </span><span style="color: #2b91af;">IMonoidalFunctor</span><span style="color: black;">&lt;<span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: red;"></span><span style="color: black;">&lt;&gt;&gt; =&gt;<span style="color: blue;"><span style="color: black;"></span><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;</span><span style="color: green;">
        </span><span style="color: blue;"><span style="color: #2b91af;">TMonoidalFunctor</span></span><span style="color: black;">&lt;</span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;.U</span>nit().Select(unit </span><span style="color: red;"></span><span style="color: black;">=&gt; value);

}

// Cannot be compiled. public static class ApplicativeFunctorExtensions // (Apply, Wrap) implements (Multiply, Unit). { // Multiply: TApplicativeFunctor<T1> x TApplicativeFunctor<T2> -> TApplicativeFunctor<T1 x T2> // Multiply: (TApplicativeFunctor<T1>, TApplicativeFunctor<T2>) -> TApplicativeFunctor<(T1, T2)> public static TApplicativeFunctor<(T1, T2)> Multiply<TApplicativeFunctor<>, T1, T2>( this TApplicativeFunctor<T1> source1, TApplicativeFunctor<T2> source2) where TApplicativeFunctor<> : IApplicativeFunctor<TApplicativeFunctor<>> => new Func<T1, T2, (T1, T2)>(ValueTuple.Create).Curry().Wrap().Apply(source1).Apply(source2);

</span><span style="color: green;">// Unit: Unit -&gt; TApplicativeFunctor&lt;Unit&gt;
</span><span style="color: blue;">public static <span style="color: black;"></span><span style="color: #2b91af;">TApplicativeFunctor</span></span><span style="color: black;">&lt;<span style="color: black;"></span><span style="color: #2b91af;">Unit</span>&gt; Unit&lt;</span><span style="color: #2b91af;">TApplicativeFunctor</span><span style="color: black;">&lt;&gt;&gt;(Unit unit = </span><span style="color: blue;">default</span><span style="color: black;">)
    </span><span style="color: blue;">where </span><span style="color: #2b91af;">TApplicativeFunctor</span><span style="color: black;">&lt;&gt; : </span><span style="color: #2b91af;">IApplicativeFunctor</span><span style="color: black;">&lt;<span style="color: black;"></span><span style="color: #2b91af;">TApplicativeFunctor</span></span><span style="color: red;"></span><span style="color: black;">&lt;&gt;&gt; =&gt; unit</span><span style="color: black;">.Wrap();

}

More Monoidal functors and applicative functors

The Lazy<>, Func<>, Func<T,> functors are also monoidal/applicative functors:

public static partial class LazyExtensions // Lazy<T> : IMonoidalFunctor<Lazy<>>
{
    // Multiply: Lazy<T1> x Lazy<T2> -> Lazy<T1 x T2>
    // Multiply: (Lazy<T1>, Lazy<T2>) -> Lazy<(T1, T2)>
    public static Lazy<(T1, T2)> Multiply<T1, T2>(this Lazy<T1> source1, Lazy<T2> source2) =>
        new Lazy<(T1, T2)>(() => (source1.Value, source2.Value));
</span><span style="color: green;">// Unit: Unit -&gt; Lazy&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Lazy</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; </span><span style="color: blue;">new </span><span style="color: #2b91af;">Lazy</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt;(() =&gt; unit);

}

public static partial class LazyExtensions // Lazy<T> : IApplicativeFunctor<Lazy<>> { // Apply: (Lazy<TSource -> TResult>, Lazy<TSource>) -> Lazy<TResult> public static Lazy<TResult> Apply<TSource, TResult>( this Lazy<Func<TSource, TResult>> selectorWrapper, Lazy<TSource> source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));

</span><span style="color: green;">// Wrap: TSource -&gt; Lazy&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Lazy</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt; Lazy&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">T </span><span style="color: black;">value) =&gt; Unit().Select(unit =&gt; value);

}

public static partial class FuncExtensions // Func<T> : IMonoidalFunctor<Func<>> { // Multiply: Func<T1> x Func<T2> -> Func<T1 x T2> // Multiply: (Func<T1>, Func<T2>) -> Func<(T1, T2)> public static Func<(T1, T2)> Multiply<T1, T2>(this Func<T1> source1, Func<T2> source2) => () => (source1(), source2());

</span><span style="color: green;">// Unit: Unit -&gt; Func&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; () =&gt; unit;

}

public static partial class FuncExtensions // Func<T> : IApplicativeFunctor<Func<>> { // Apply: (Func<TSource -> TResult>, Func<TSource>) -> Func<TResult> public static Func<TResult> Apply<TSource, TResult>( this Func<Func<TSource, TResult>> selectorWrapper, Func<TSource> source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));

</span><span style="color: green;">// Wrap: TSource -&gt; Func&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt; Func&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">T </span><span style="color: black;">value) =&gt; Unit().Select(unit =&gt; value);

}

public static partial class FuncExtensions // Func<T, TResult> : IMonoidalFunctor<Func<T,>> { // Multiply: Func<T, T1> x Func<T, T2> -> Func<T, T1 x T2> // Multiply: (Func<T, T1>, Func<T, T2>) -> Func<T, (T1, T2)> public static Func<T, (T1, T2)> Multiply<T, T1, T2>(this Func<T, T1> source1, Func<T, T2> source2) => value => (source1(value), source2(value));

</span><span style="color: green;">// Unit: Unit -&gt; Func&lt;T, Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">, </span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; _ =&gt; unit;

}

public static partial class FuncExtensions // Func<T, TResult> : IApplicativeFunctor<Func<T,>> { // Apply: (Func<T, TSource -> TResult>, Func<T, TSource>) -> Func<T, TResult> public static Func<T, TResult> Apply<T, TSource, TResult>( this Func<T, Func<TSource, TResult>> selectorWrapper, Func<T, TSource> source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));

</span><span style="color: green;">// Wrap: TSource -&gt; Func&lt;T, TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">, </span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt; Func&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">, </span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">TSource </span><span style="color: black;">value) =&gt; Unit&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;().Select(unit =&gt; value);

}

public static partial class OptionalExtensions // Optional<T> : IMonoidalFunctor<Optional<>> { // Multiply: Optional<T1> x Optional<T2> -> Optional<T1 x T2> // Multiply: (Optional<T1>, Optional<T2>) -> Optional<(T1, T2)> public static Optional<(T1, T2)> Multiply<T1, T2>(this Optional<T1> source1, Optional<T2> source2) => new Optional<(T1, T2)>(() => source1.HasValue && source2.HasValue ? (true, (source1.Value, source2.Value)) : (false, (default, default)));

</span><span style="color: green;">// Unit: Unit -&gt; Optional&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Optional</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt;
    </span><span style="color: blue;">new </span><span style="color: #2b91af;">Optional</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt;(() =&gt; (</span><span style="color: blue;">true</span><span style="color: black;">, unit));

}

public static partial class OptionalExtensions // Optional<T> : IApplicativeFunctor<Optional<>> { // Apply: (Optional<TSource -> TResult>, Optional<TSource>) -> Optional<TResult> public static Optional<TResult> Apply<TSource, TResult>( this Optional<Func<TSource, TResult>> selectorWrapper, Optional<TSource> source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2));

</span><span style="color: green;">// Wrap: TSource -&gt; Optional&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Optional</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt; Optional&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">T </span><span style="color: black;">value) =&gt; Unit().Select(unit =&gt; value);

}

The ValueTuple<> and Task<> functors are monoidal/applicative functors too. Notice their Multiply/Apply methods cannot defer the execution, and Task<>’s Multiply/Apply methods are impure.

public static partial class ValueTupleExtensions // ValueTuple<T> : IMonoidalFunctor<ValueTuple<>>
{
    // Multiply: ValueTuple<T1> x ValueTuple<T2> -> ValueTuple<T1 x T2>
    // Multiply: (ValueTuple<T1>, ValueTuple<T2>) -> ValueTuple<(T1, T2)>
    public static ValueTuple<(T1, T2)> Multiply<T1, T2>(this ValueTuple<T1> source1, ValueTuple<T2> source2) =>
        new ValueTuple<(T1, T2)>((source1.Item1, source2.Item1)); // Immediate execution.
// Unit: Unit -&gt; ValueTuple&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">ValueTuple</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; </span><span style="color: blue;">new </span><span style="color: #2b91af;">ValueTuple</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt;(unit);

}

public static partial class ValueTupleExtensions // ValueTuple<T> : IApplicativeFunctor<ValueTuple<>> { // Apply: (ValueTuple<TSource -> TResult>, ValueTuple<TSource>) -> ValueTuple<TResult> public static ValueTuple<TResult> Apply<TSource, TResult>( this ValueTuple<Func<TSource, TResult>> selectorWrapper, ValueTuple<TSource> source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2)); // Immediate execution.

// Wrap: TSource -&gt; ValueTuple&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">ValueTuple</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt; ValueTuple&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">T </span><span style="color: black;">value) =&gt; Unit().Select(unit =&gt; value);

} public static partial class TaskExtensions // Task<T> : IMonoidalFunctor<Task<>> { // Multiply: Task<T1> x Task<T2> -> Task<T1 x T2> // Multiply: (Task<T1>, Task<T2>) -> Task<(T1, T2)> public static async Task<(T1, T2)> Multiply<T1, T2>(this Task<T1> source1, Task<T2> source2) => ((await source1), (await source2)); // Immediate execution, impure.

// Unit: Unit -&gt; Task&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Task</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Unit</span><span style="color: black;">&gt; Unit(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; System.Threading.Tasks.</span><span style="color: #2b91af;">Task</span><span style="color: black;">.FromResult(unit);

}

public static partial class TaskExtensions // Task<T> : IApplicativeFunctor<Task<>> { // Apply: (Task<TSource -> TResult>, Task<TSource>) -> Task<TResult> public static Task<TResult> Apply<TSource, TResult>( this Task<Func<TSource, TResult>> selectorWrapper, Task<TSource> source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2)); // Immediate execution, impure.

// Wrap: TSource -&gt; Task&lt;TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: #2b91af;">Task</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt; Task&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">T </span><span style="color: black;">value) =&gt; Unit().Select(unit =&gt; value);

}

It is easy to verify all the above (Multiply, Unit) method pairs preserve the monoid laws, and all the above (Apply, Wrap) method pairs satisfy the applicative laws. However, not any (Multiply, Unit) or any (Apply, Wrap) can automatically satisfy the laws. Take the ValueTuple<T,> functor as example:

public static partial class ValueTupleExtensions // ValueTuple<T1, T2 : IMonoidalFunctor<ValueTuple<T,>>
{
    // Multiply: ValueTuple<T, T1> x ValueTuple<T, T2> -> ValueTuple<T, T1 x T2>
    // Multiply: (ValueTuple<T, T1>, ValueTuple<T, T2>) -> ValueTuple<T, (T1, T2)>
    public static (T, (T1, T2)) Multiply<T, T1, T2>(this (T, T1) source1, (T, T2) source2) =>
        (source1.Item1, (source1.Item2, source2.Item2)); // Immediate execution.
// Unit: Unit -&gt; ValueTuple&lt;Unit&gt;
</span><span style="color: blue;">public static </span><span style="color: black;">(</span><span style="color: #2b91af;">T</span><span style="color: black;">, </span><span style="color: #2b91af;">Unit</span><span style="color: black;">) Unit&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;(</span><span style="color: #2b91af;">Unit </span><span style="color: black;">unit = </span><span style="color: blue;">default</span><span style="color: black;">) =&gt; (</span><span style="color: blue;">default</span><span style="color: black;">, unit);

}

public static partial class ValueTupleExtensions // ValueTuple<T, TResult> : IApplicativeFunctor<ValueTuple<T,>> { // Apply: (ValueTuple<T, TSource -> TResult>, ValueTuple<T, TSource>) -> ValueTuple<T, TResult> public static (T, TResult) Apply<T, TSource, TResult>( this (T, Func<TSource, TResult>) selectorWrapper, (T, TSource) source) => selectorWrapper.Multiply(source).Select(product => product.Item1(product.Item2)); // Immediate execution.

// Wrap: TSource -&gt; ValueTuple&lt;T, TSource&gt;
</span><span style="color: blue;">public static </span><span style="color: black;">(</span><span style="color: #2b91af;">T</span><span style="color: black;">, </span><span style="color: #2b91af;">TSource</span><span style="color: black;">) ValueTuple&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">, </span><span style="color: #2b91af;">TSource</span><span style="color: black;">&gt;(</span><span style="color: blue;">this </span><span style="color: #2b91af;">TSource </span><span style="color: black;">value) =&gt; Unit&lt;</span><span style="color: #2b91af;">T</span><span style="color: black;">&gt;().Select(unit =&gt; value);

}

The above (Multiply, Unit) implementations cannot preserve the left unit law:

internal static void MonoidalFunctorLaws()
{
    (string, int) source = ("a", 1);
    (string, Unit) unit = Unit<string>();
    (string, int) source1 = ("b", 2);
    (string, char) source2 = ("c", '@');
    (string, bool) source3 = ("d", true);
</span><span style="color: green;">// Associativity preservation: source1.Multiply(source2).Multiply(source3).Select(Associator) == source1.Multiply(source2.Multiply(source3)).
</span><span style="color: black;">source1.Multiply(source2).Multiply(source3).Select(Associator).WriteLine(); </span><span style="color: green;">// (b, (2, (@, True)))
</span><span style="color: black;">source1.Multiply(source2.Multiply(source3)).WriteLine(); </span><span style="color: green;">// (b, (2, (@, True)))
// Left unit preservation: unit.Multiply(source).Select(LeftUnitor) == source.
</span><span style="color: black;">unit.Multiply(source).Select(LeftUnitor).WriteLine(); </span><span style="color: green;">// (, 1)
// Right unit preservation: source == source.Multiply(unit).Select(RightUnitor).
</span><span style="color: black;">source.Multiply(unit).Select(RightUnitor).WriteLine(); </span><span style="color: green;">// (a, 1)

}

And the above (Apply, Wrap) implementation breaks all applicative laws:

internal static void ApplicativeLaws()
{
    (string, int) source = ("a", 1);
    Func<int, double> selector = int32 => Math.Sqrt(int32);
    (string, Func<int, double>) selectorWrapper1 = 
        ("b", new Func<int, double>(int32 => Math.Sqrt(int32)));
    (string, Func<double, string>) selectorWrapper2 =
        ("c", new Func<double, string>(@double => @double.ToString("0.00")));
    Func<Func<double, string>, Func<Func<int, double>, Func<int, string>>> o = 
        new Func<Func<double, string>, Func<int, double>, Func<int, string>>(Linq.FuncExtensions.o).Curry();
    int value = 5;
</span><span style="color: green;">// Functor preservation: source.Select(selector) == selector.Wrap().Apply(source).
</span><span style="color: black;">source.Select(selector).WriteLine(); </span><span style="color: green;">// (a, 1)
</span><span style="color: black;">selector.ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;&gt;().Apply(source).WriteLine(); </span><span style="color: green;">// (, 1)
// Identity preservation: Id.Wrap().Apply(source) == source.
</span><span style="color: blue;">new </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">int</span><span style="color: black;">&gt;(</span><span style="color: #2b91af;">Functions</span><span style="color: black;">.Id).ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">int</span><span style="color: black;">&gt;&gt;().Apply(source).WriteLine(); </span><span style="color: green;">// (, 1)
// Composition preservation: o.Curry().Wrap().Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source) == selectorWrapper2.Apply(selectorWrapper1.Apply(source)).
</span><span style="color: black;">o.ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">double</span><span style="color: black;">, </span><span style="color: blue;">string</span><span style="color: black;">&gt;, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">string</span><span style="color: black;">&gt;&gt;&gt;&gt;()
    .Apply(selectorWrapper2).Apply(selectorWrapper1).Apply(source).WriteLine(); </span><span style="color: green;">// (, 1.00)
</span><span style="color: black;">selectorWrapper2.Apply(selectorWrapper1.Apply(source)).WriteLine(); </span><span style="color: green;">// (c, 1.00)
// Homomorphism: selector.Wrap().Apply(value.Wrap()) == selector(value).Wrap().
</span><span style="color: black;">selector.ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;&gt;().Apply(value.ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: blue;">int</span><span style="color: black;">&gt;()).WriteLine(); </span><span style="color: green;">// (, 2.23606797749979)
</span><span style="color: black;">selector(value).ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;().WriteLine(); </span><span style="color: green;">// (, 2.23606797749979)
// Interchange: selectorWrapper.Apply(value.Wrap()) == (selector =&gt; selector(value)).Wrap().Apply(selectorWrapper).
</span><span style="color: black;">selectorWrapper1.Apply(value.ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: blue;">int</span><span style="color: black;">&gt;()).WriteLine(); </span><span style="color: green;">// (b, 2.23606797749979)
</span><span style="color: blue;">new </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;, </span><span style="color: blue;">double</span><span style="color: black;">&gt;(function =&gt; function(value))
    .ValueTuple&lt;</span><span style="color: blue;">string</span><span style="color: black;">, </span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: #2b91af;">Func</span><span style="color: black;">&lt;</span><span style="color: blue;">int</span><span style="color: black;">, </span><span style="color: blue;">double</span><span style="color: black;">&gt;, </span><span style="color: blue;">double</span><span style="color: black;">&gt;&gt;().Apply(selectorWrapper1).WriteLine(); </span><span style="color: green;">// (, 2.23606797749979)

}

No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website