Table of Contents

Class TapExtensions

Namespace
Trellis
Assembly
Trellis.Core.dll

Provides extension methods for executing side effects on successful Results without changing the Result.

public static class TapExtensions
Inheritance
TapExtensions
Inherited Members

Examples

var result = GetUser(id)
    .Tap(user => _logger.LogInformation("Found user: {Name}", user.Name))
    .Bind(user => ValidateUser(user))
    .Tap(() => _metrics.IncrementCounter("user.validated"));
// Without cancellation token
var result = EmailAddress.TryCreate("user@example.com")
    .Combine(UserId.TryCreate("123"))
    .Tap((email, userId) => _logger.LogInformation("Processing user {UserId} with email {Email}", userId, email))
    .Tap((email, userId) => _metrics.RecordUserCreation())
    .Bind((email, userId) => CreateUser(email, userId));

// With cancellation token (closure capture)
var ct = cancellationToken;
var result = await EmailAddress.TryCreate("user@example.com")
    .Combine(UserId.TryCreate("123"))
    .TapAsync((email, userId) => LogAsync(email, userId, ct))
    .BindAsync((email, userId) => CreateUserAsync(email, userId, ct));

Remarks

Tap is useful for performing side effects (like logging, auditing, or debugging) in a functional pipeline without breaking the chain. The action is only executed if the Result is successful, and the original Result is always returned unchanged. This allows you to "peek" at values flowing through the pipeline.

Methods

Tap<TValue>(Result<TValue>, Action)

Executes the given action if the result is a success. Returns the original result unchanged.

public static Result<TValue> Tap<TValue>(this Result<TValue> result, Action action)

Parameters

result Result<TValue>

The result to tap.

action Action

The action to execute if the result is successful.

Returns

Result<TValue>

The original result unchanged.

Type Parameters

TValue

Type of the result value.

Tap<TValue>(Result<TValue>, Action<TValue>)

Executes the given action with the value if the result is a success. Returns the original result unchanged.

public static Result<TValue> Tap<TValue>(this Result<TValue> result, Action<TValue> action)

Parameters

result Result<TValue>

The result to tap.

action Action<TValue>

The action to execute with the value if the result is successful.

Returns

Result<TValue>

The original result unchanged.

Type Parameters

TValue

Type of the result value.

Tap<T1, T2>(Result<(T1, T2)>, Action<T1, T2>)

Executes a side effect action on a successful 2-element tuple result without modifying the result.

public static Result<(T1, T2)> Tap<T1, T2>(this Result<(T1, T2)> result, Action<T1, T2> action)

Parameters

result Result<(T1, T2)>

The result containing a 2-element tuple.

action Action<T1, T2>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Tap((arg1, arg2) => _logger.LogInfo($"Values: {arg1 + ", " + arg2}"))
    .Bind((arg1, arg2) => ProcessData(arg1, arg2));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3>(Result<(T1, T2, T3)>, Action<T1, T2, T3>)

Executes a side effect action on a successful 3-element tuple result without modifying the result.

public static Result<(T1, T2, T3)> Tap<T1, T2, T3>(this Result<(T1, T2, T3)> result, Action<T1, T2, T3> action)

Parameters

result Result<(T1, T2, T3)>

The result containing a 3-element tuple.

action Action<T1, T2, T3>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Tap((arg1, arg2, arg3) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3}"))
    .Bind((arg1, arg2, arg3) => ProcessData(arg1, arg2, arg3));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3, T4>(Result<(T1, T2, T3, T4)>, Action<T1, T2, T3, T4>)

Executes a side effect action on a successful 4-element tuple result without modifying the result.

public static Result<(T1, T2, T3, T4)> Tap<T1, T2, T3, T4>(this Result<(T1, T2, T3, T4)> result, Action<T1, T2, T3, T4> action)

Parameters

result Result<(T1, T2, T3, T4)>

The result containing a 4-element tuple.

action Action<T1, T2, T3, T4>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3, T4)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

T4

The type of element 4 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Combine(Field4.TryCreate("value4"))
    .Tap((arg1, arg2, arg3, arg4) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4}"))
    .Bind((arg1, arg2, arg3, arg4) => ProcessData(arg1, arg2, arg3, arg4));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3, T4, T5>(Result<(T1, T2, T3, T4, T5)>, Action<T1, T2, T3, T4, T5>)

Executes a side effect action on a successful 5-element tuple result without modifying the result.

public static Result<(T1, T2, T3, T4, T5)> Tap<T1, T2, T3, T4, T5>(this Result<(T1, T2, T3, T4, T5)> result, Action<T1, T2, T3, T4, T5> action)

Parameters

result Result<(T1, T2, T3, T4, T5)>

The result containing a 5-element tuple.

action Action<T1, T2, T3, T4, T5>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3, T4, T5)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

T4

The type of element 4 in the tuple.

T5

The type of element 5 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Combine(Field4.TryCreate("value4"))
    .Combine(Field5.TryCreate("value5"))
    .Tap((arg1, arg2, arg3, arg4, arg5) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5}"))
    .Bind((arg1, arg2, arg3, arg4, arg5) => ProcessData(arg1, arg2, arg3, arg4, arg5));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3, T4, T5, T6>(Result<(T1, T2, T3, T4, T5, T6)>, Action<T1, T2, T3, T4, T5, T6>)

Executes a side effect action on a successful 6-element tuple result without modifying the result.

public static Result<(T1, T2, T3, T4, T5, T6)> Tap<T1, T2, T3, T4, T5, T6>(this Result<(T1, T2, T3, T4, T5, T6)> result, Action<T1, T2, T3, T4, T5, T6> action)

Parameters

result Result<(T1, T2, T3, T4, T5, T6)>

The result containing a 6-element tuple.

action Action<T1, T2, T3, T4, T5, T6>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3, T4, T5, T6)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

T4

The type of element 4 in the tuple.

T5

The type of element 5 in the tuple.

T6

The type of element 6 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Combine(Field4.TryCreate("value4"))
    .Combine(Field5.TryCreate("value5"))
    .Combine(Field6.TryCreate("value6"))
    .Tap((arg1, arg2, arg3, arg4, arg5, arg6) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6}"))
    .Bind((arg1, arg2, arg3, arg4, arg5, arg6) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3, T4, T5, T6, T7>(Result<(T1, T2, T3, T4, T5, T6, T7)>, Action<T1, T2, T3, T4, T5, T6, T7>)

Executes a side effect action on a successful 7-element tuple result without modifying the result.

public static Result<(T1, T2, T3, T4, T5, T6, T7)> Tap<T1, T2, T3, T4, T5, T6, T7>(this Result<(T1, T2, T3, T4, T5, T6, T7)> result, Action<T1, T2, T3, T4, T5, T6, T7> action)

Parameters

result Result<(T1, T2, T3, T4, T5, T6, T7)>

The result containing a 7-element tuple.

action Action<T1, T2, T3, T4, T5, T6, T7>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3, T4, T5, T6, T7)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

T4

The type of element 4 in the tuple.

T5

The type of element 5 in the tuple.

T6

The type of element 6 in the tuple.

T7

The type of element 7 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Combine(Field4.TryCreate("value4"))
    .Combine(Field5.TryCreate("value5"))
    .Combine(Field6.TryCreate("value6"))
    .Combine(Field7.TryCreate("value7"))
    .Tap((arg1, arg2, arg3, arg4, arg5, arg6, arg7) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7}"))
    .Bind((arg1, arg2, arg3, arg4, arg5, arg6, arg7) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6, arg7));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3, T4, T5, T6, T7, T8>(Result<(T1, T2, T3, T4, T5, T6, T7, T8)>, Action<T1, T2, T3, T4, T5, T6, T7, T8>)

Executes a side effect action on a successful 8-element tuple result without modifying the result.

public static Result<(T1, T2, T3, T4, T5, T6, T7, T8)> Tap<T1, T2, T3, T4, T5, T6, T7, T8>(this Result<(T1, T2, T3, T4, T5, T6, T7, T8)> result, Action<T1, T2, T3, T4, T5, T6, T7, T8> action)

Parameters

result Result<(T1, T2, T3, T4, T5, T6, T7, T8)>

The result containing a 8-element tuple.

action Action<T1, T2, T3, T4, T5, T6, T7, T8>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3, T4, T5, T6, T7, T8)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

T4

The type of element 4 in the tuple.

T5

The type of element 5 in the tuple.

T6

The type of element 6 in the tuple.

T7

The type of element 7 in the tuple.

T8

The type of element 8 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Combine(Field4.TryCreate("value4"))
    .Combine(Field5.TryCreate("value5"))
    .Combine(Field6.TryCreate("value6"))
    .Combine(Field7.TryCreate("value7"))
    .Combine(Field8.TryCreate("value8"))
    .Tap((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7 + ", " + arg8}"))
    .Bind((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.

Tap<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>, Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>)

Executes a side effect action on a successful 9-element tuple result without modifying the result.

public static Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> Tap<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> result, Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)

Parameters

result Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>

The result containing a 9-element tuple.

action Action<T1, T2, T3, T4, T5, T6, T7, T8, T9>

The side effect action to execute on the tuple elements if successful.

Returns

Result<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>

The original result unchanged.

Type Parameters

T1

The type of element 1 in the tuple.

T2

The type of element 2 in the tuple.

T3

The type of element 3 in the tuple.

T4

The type of element 4 in the tuple.

T5

The type of element 5 in the tuple.

T6

The type of element 6 in the tuple.

T7

The type of element 7 in the tuple.

T8

The type of element 8 in the tuple.

T9

The type of element 9 in the tuple.

Examples

var result = FirstName.TryCreate("John")
    .Combine(LastName.TryCreate("Doe"))
    .Combine(Field3.TryCreate("value3"))
    .Combine(Field4.TryCreate("value4"))
    .Combine(Field5.TryCreate("value5"))
    .Combine(Field6.TryCreate("value6"))
    .Combine(Field7.TryCreate("value7"))
    .Combine(Field8.TryCreate("value8"))
    .Combine(Field9.TryCreate("value9"))
    .Tap((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) => _logger.LogInfo($"Values: {arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ", " + arg7 + ", " + arg8 + ", " + arg9}"))
    .Bind((arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) => ProcessData(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));

Remarks

If the result is a failure, the action is not executed and the failure is returned unchanged. This enables safe side effects in Railway Oriented Programming chains.