Skip to content

IFinResponse Hierarchy Reference

This appendix is a reference document that provides a complete overview of Functorium’s IFinResponse interface hierarchy at a glance. It describes in detail the role of each interface, its constraints, and how it is implemented in FinResponse<A>.


IFinResponse Non-generic marker (IsSucc/IsFail)
├── IFinResponse<out A> Covariant interface (read-only)
IFinResponseFactory<TSelf> CRTP factory (CreateFail)
IFinResponseWithError Error access (Error property)
FinResponse<A> Discriminated Union
├── : IFinResponse<A> Covariant interface implementation
├── : IFinResponseFactory<FinResponse<A>> CRTP factory implementation
├── sealed record Succ(A Value) Success case
└── sealed record Fail(Error Error) Failure case
└── : IFinResponseWithError Error access only in Fail

public interface IFinResponse
{
bool IsSucc { get; }
bool IsFail { get; }
}
ItemDescription
RoleMinimal interface for reading success/failure status in Pipelines
VarianceNone (non-generic)
Used by PipelinesLogging, Tracing, Metrics, Transaction, Caching
Used as constraintwhere TResponse : IFinResponse

2. IFinResponse<out A> (Covariant Interface)

Section titled “2. IFinResponse<out A> (Covariant Interface)”
public interface IFinResponse<out A> : IFinResponse
{
}
ItemDescription
RoleGeneric extension supporting covariance
VarianceCovariant (out A)
InheritanceInherits from IFinResponse
MeaningFinResponse<Dog> can be referenced as IFinResponse<Animal>

3. IFinResponseFactory<TSelf> (CRTP Factory)

Section titled “3. IFinResponseFactory<TSelf> (CRTP Factory)”
public interface IFinResponseFactory<TSelf>
where TSelf : IFinResponseFactory<TSelf>
{
static abstract TSelf CreateFail(Error error);
}
ItemDescription
RoleFactory for creating failure responses in Pipelines
PatternCRTP (Curiously Recurring Template Pattern)
Key methodstatic abstract TSelf CreateFail(Error error)
Used by PipelinesValidation, Exception (Create-Only), and all Read+Create Pipelines
Used as constraintwhere TResponse : IFinResponseFactory<TResponse>
public interface IFinResponseWithError
{
Error Error { get; }
}
ItemDescription
RoleAccess Error information on failure
ImplementationImplemented only in FinResponse<A>.Fail
Usageif (response is IFinResponseWithError fail) { ... fail.Error ... }
Used by PipelinesLogging Pipeline (recording error messages)

public abstract record FinResponse<A> : IFinResponse<A>, IFinResponseFactory<FinResponse<A>>
public sealed record Succ(A Value) : FinResponse<A>
{
public override bool IsSucc => true;
public override bool IsFail => false;
}
public sealed record Fail(Error Error) : FinResponse<A>, IFinResponseWithError
{
public override bool IsSucc => false;
public override bool IsFail => true;
Error IFinResponseWithError.Error => Error;
}
MethodSignatureDescription
MatchB Match<B>(Func<A, B> Succ, Func<Error, B> Fail)Branch on success/failure
Match (void)void Match(Action<A> Succ, Action<Error> Fail)Execute branch (no return)
MapFinResponse<B> Map<B>(Func<A, B> f)Transform success value
MapFailFinResponse<A> MapFail(Func<Error, Error> f)Transform failure error
BiMapFinResponse<B> BiMap<B>(Func<A, B> Succ, Func<Error, Error> Fail)Transform both success/failure
BindFinResponse<B> Bind<B>(Func<A, FinResponse<B>> f)Monadic bind
BiBindFinResponse<B> BiBind<B>(Func<A, FinResponse<B>> Succ, Func<Error, FinResponse<B>> Fail)Bidirectional monadic bind
BindFailFinResponse<A> BindFail(Func<Error, FinResponse<A>> Fail)Failure track bind
SelectFinResponse<B> Select<B>(Func<A, B> f)LINQ select support
SelectManyFinResponse<C> SelectMany<B, C>(...)LINQ from/select support
ThrowIfFailA ThrowIfFail()Throws on failure, returns value on success
IfFail (value)A IfFail(A alternative)Returns alternative value on failure
IfFail (Func)A IfFail(Func<Error, A> Fail)Generates alternative value via function on failure
IfFail (Action)void IfFail(Action<Error> Fail)Executes side effect on failure
IfSuccvoid IfSucc(Action<A> Succ)Executes side effect on success
CreateFailstatic FinResponse<A> CreateFail(Error error)CRTP factory implementation
// Value → FinResponse (Succ)
public static implicit operator FinResponse<A>(A value) => new Succ(value);
// Error → FinResponse (Fail)
public static implicit operator FinResponse<A>(Error error) => new Fail(error);
// Boolean operators — supports if/else pattern matching
public static bool operator true(FinResponse<A> ma) => ma.IsSucc;
public static bool operator false(FinResponse<A> ma) => ma.IsFail;
// Choice operator — selects the first successful value
public static FinResponse<A> operator |(FinResponse<A> lhs, FinResponse<A> rhs) =>
lhs.IsSucc ? lhs : rhs;
public static class FinResponse
{
public static FinResponse<A> Succ<A>(A value) => new FinResponse<A>.Succ(value);
public static FinResponse<A> Succ<A>() where A : new() => new FinResponse<A>.Succ(new A());
public static FinResponse<A> Fail<A>(Error error) => new FinResponse<A>.Fail(error);
}

Pipeline TResponse Constraint Capability
────────────────────────── ─────────────────────────────────────────────── ────────────
Metrics Pipeline IFinResponse, IFinResponseFactory<TResponse> Read + Create
Tracing Pipeline IFinResponse, IFinResponseFactory<TResponse> Read + Create
Logging Pipeline IFinResponse, IFinResponseFactory<TResponse> Read + Create
Validation Pipeline IFinResponseFactory<TResponse> CreateFail
Caching Pipeline IFinResponse, IFinResponseFactory<TResponse> Read + Create
Exception Pipeline IFinResponseFactory<TResponse> CreateFail
Transaction Pipeline IFinResponse, IFinResponseFactory<TResponse> Read + Create
Custom Pipeline (User-defined) Varies

The following appendix provides a comparative analysis of the interface constraint approach versus alternative approaches such as reflection, dynamic, and Source Generators.

Appendix B: Pipeline Constraints vs Alternatives