Expression evaluators, with possible short circuit evaluation I'm writing a project, and the part I'm doing now is getting bloated real fast. How can I remove this nested if statements, but still have the same behaviour?

It would be nice the the resulting code was succinct, and extra local flags weren't required. This might not look so bad now, but I'm planning on writing more methods, up to T16, you can imagine how bad these nested if statements will get.

using ContainerExpressions.Containers;
using System;

namespace ContainerExpressions.Expressions.Core
{
    internal static class Compose
    {
        public static Response&lt;T&gt; Evaluate&lt;T&gt;(Func&lt;Response&lt;T&gt;&gt; func) =&gt; func();

        public static Response&lt;TResult&gt; Evaluate&lt;T1, TResult&gt;(Func&lt;Response&lt;T1&gt;&gt; func1, Func&lt;T1, Response&lt;TResult&gt;&gt; funcResult)
        {
            var response = new Response&lt;TResult&gt;();

            var result = func1();
            if (result)
            {
                response = response.WithValue(funcResult(result));
            }

            return response;
        }

        public static Response&lt;TResult&gt; Evaluate&lt;T1, T2, TResult&gt;(Func&lt;Response&lt;T1&gt;&gt; func1, Func&lt;T1, Response&lt;T2&gt;&gt; func2, Func&lt;T2, Response&lt;TResult&gt;&gt; funcResult)
        {
            var response = new Response&lt;TResult&gt;();

            var result1 = func1();
            if (result1)
            {
                var result2 = func2(result1);
                if (result2)
                {
                    response = response.WithValue(funcResult(result2));
                }
            }

            return response;
        }

        public static Response&lt;TResult&gt; Evaluate&lt;T1, T2, T3, TResult&gt;(Func&lt;Response&lt;T1&gt;&gt; func1, Func&lt;T1, Response&lt;T2&gt;&gt; func2, Func&lt;T2, Response&lt;T3&gt;&gt; func3, Func&lt;T3, Response&lt;TResult&gt;&gt; funcResult)
        {
            var response = new Response&lt;TResult&gt;();

            var result1 = func1();
            if (result1)
            {
                var result2 = func2(result1);
                if (result2)
                {
                    var result3 = func3(result2);
                    if (result3)
                    {
                        response = response.WithValue(funcResult(result3));
                    }
                }
            }

            return response;
        }
    }
}
If your code will always behave as the parts shown, you can refactor it to early-out returns. I show your Evaluate&lt;T1, T2, T3, TResult&gt;(...) as an example:

public static Response&lt;TResult&gt; Evaluate&lt;T1, T2, T3, TResult&gt;(Func&lt;Response&lt;T1&gt;&gt; func1, Func&lt;T1, Response&lt;T2&gt;&gt; func2, Func&lt;T2, Response&lt;T3&gt;&gt; func3, Func&lt;T3, Response&lt;TResult&gt;&gt; funcResult)
{
    var response = new Response&lt;TResult&gt;();

    if (!func1()) return response;
    if (!func2(true)) return response;
    if (!func3(true)) return response;
    return response.WithValue(funcResult(result3));
}


So you get rid of the nesting if statements. And you don't need the local flag variables since you know that the value is true.