-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System.Collections.Immutable; | ||
|
||
namespace Funcky.Test; | ||
|
||
public sealed class UpCastTest | ||
{ | ||
[Fact] | ||
public void UpCastsReferenceTypeToObject() | ||
{ | ||
const string arbitraryStringValue = "string"; | ||
|
||
Option<object> option = UpCast<object>.From(Option.Return(arbitraryStringValue)); | ||
FunctionalAssert.Some(arbitraryStringValue, option); | ||
|
||
Either<Unit, object> either = UpCast<object>.From(Either<Unit>.Return(arbitraryStringValue)); | ||
FunctionalAssert.Right(arbitraryStringValue, either); | ||
|
||
Result<object> result = UpCast<object>.From(Result.Return(arbitraryStringValue)); | ||
FunctionalAssert.Ok(arbitraryStringValue, result); | ||
|
||
Lazy<object> lazy = UpCast<object>.From(Lazy.Return(arbitraryStringValue)); | ||
Assert.Equal(arbitraryStringValue, lazy.Value); | ||
} | ||
|
||
[Fact] | ||
public void UpCastsValueTypeToObject() | ||
{ | ||
const int arbitraryIntegerValue = 10; | ||
|
||
Option<object> option = UpCast<object>.From(Option.Return(arbitraryIntegerValue)); | ||
FunctionalAssert.Some(arbitraryIntegerValue, option); | ||
|
||
Either<Unit, object> either = UpCast<object>.From(Either<Unit>.Return(arbitraryIntegerValue)); | ||
FunctionalAssert.Right(arbitraryIntegerValue, either); | ||
|
||
Result<object> result = UpCast<object>.From(Result.Return(arbitraryIntegerValue)); | ||
FunctionalAssert.Ok(arbitraryIntegerValue, result); | ||
|
||
Lazy<object> lazy = UpCast<object>.From(Lazy.Return(arbitraryIntegerValue)); | ||
Assert.Equal(arbitraryIntegerValue, lazy.Value); | ||
} | ||
|
||
[Fact] | ||
public void UpCastsToInterface() | ||
{ | ||
var arbitraryImplementationValue = ImmutableArray<string>.Empty; | ||
|
||
Option<IEnumerable<string>> option = UpCast<IEnumerable<string>>.From(Option.Return(arbitraryImplementationValue)); | ||
FunctionalAssert.Some(arbitraryImplementationValue, option); | ||
|
||
Either<Unit, IEnumerable<string>> either = UpCast<IEnumerable<string>>.From(Either<Unit>.Return(arbitraryImplementationValue)); | ||
FunctionalAssert.Right(arbitraryImplementationValue, either); | ||
|
||
Result<IEnumerable<string>> result = UpCast<IEnumerable<string>>.From(Result.Return(arbitraryImplementationValue)); | ||
FunctionalAssert.Ok(arbitraryImplementationValue, result); | ||
|
||
Lazy<IEnumerable<string>> lazy = UpCast<IEnumerable<string>>.From(Lazy.Return(arbitraryImplementationValue)); | ||
Assert.Equal(arbitraryImplementationValue, lazy.Value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Funcky; | ||
|
||
/// <summary>Functions to upcast monad values.</summary> | ||
public static class UpCast<TResult> | ||
where TResult : notnull | ||
{ | ||
/// <summary>Upcasts an <see cref="Option{TItem}"/>'s item to <typeparamref name="TResult"/>.</summary> | ||
/// <example> | ||
/// Upcasting an option's item from <see cref="string"/> to <see cref="object"/>: | ||
/// <code><![CDATA[ | ||
/// Option<object> result = UpCast<object>.From(Option.Return("hello world")); | ||
/// ]]></code></example> | ||
public static Option<TResult> From<TItem>(Option<TItem> option) | ||
where TItem : TResult | ||
=> option.Select(From); | ||
|
||
/// <summary>Upcasts the right side of an <see cref="Either{TLeft,TRight}"/> to <typeparamref name="TResult"/>.</summary> | ||
/// <example> | ||
/// Upcasting an either's right value from <see cref="string"/> to <see cref="object"/>: | ||
/// <code><![CDATA[ | ||
/// Either<Error, object> result = UpCast<object>.From(Either<Error>.Return("hello world")); | ||
/// ]]></code></example> | ||
public static Either<TLeft, TResult> From<TLeft, TRight>(Either<TLeft, TRight> either) | ||
where TLeft : notnull | ||
where TRight : TResult | ||
=> either.Select(From); | ||
|
||
/// <summary>Upcasts the success result of a <see cref="Result{TValidResult}"/> to <typeparamref name="TResult"/>.</summary> | ||
/// <example> | ||
/// Upcasting a result's success value from <see cref="string"/> to <see cref="object"/>: | ||
/// <code><![CDATA[ | ||
/// Result<object> result = UpCast<object>.From(Result.Return("hello world")); | ||
/// ]]></code></example> | ||
public static Result<TResult> From<TValidResult>(Result<TValidResult> result) | ||
where TValidResult : TResult | ||
=> result.Select(From); | ||
|
||
/// <summary>Upcasts the value of a <see cref="Lazy{TValidResult}"/> to <typeparamref name="TResult"/>.</summary> | ||
/// <example> | ||
/// Upcasting a lazy's value from <see cref="string"/> to <see cref="object"/>: | ||
/// <code><![CDATA[ | ||
/// Lazy<object> result = UpCast<object>.From(Lazy.Return("hello world")); | ||
/// ]]></code></example> | ||
[SuppressMessage("", "IL2091: DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter", Justification = "Public parameterless constructor is only used when a Lazy is created without providing a value or func.")] | ||
public static Lazy<TResult> From<T>(Lazy<T> lazy) | ||
where T : TResult | ||
=> lazy.Select(From); | ||
|
||
private static TResult From<TValue>(TValue value) | ||
where TValue : TResult | ||
=> value; | ||
} |