Closed FreeApophis closed 5 months ago
I would love to have something like Enumerable.Cast
.
Something I dislike about Cast
however, is that there is no compile-time checks.
Edit: I just realized that my extension method isn't useful because you'd always had to specify both types :/
I feel like most cases you want to cast upwards, so a CastUp
or Upcast
method would be helpful to avoid mistakes:
public static Option<TResult> Upcast<TItem, TResult>(this Option<TItem> option)
where TItem : notnull, TResult
where TResult : notnull => ...
~~ImmutableArray has an extension method like this:
ImmutableArray.CastUp
~~
The Upcast is only possible with the two type parameters, but you could theoretically do something like this, to do type-deduction on the Option.
class UpCast<TResult>
where TResult : notnull
{
public From<TItem>(Option<T> option)
where TItem : notnull, TResult
{
// ...
}
}
Here are three possible variants which would be internally to the Option
public readonly partial struct Option<TItem>
where TItem : notnull
{
[Pure]
public Option<TResult> Cast<TResult>()
where TResult : class
=> _hasItem
? Option.Some((TResult)(object)_item)
: Option<TResult>.None;
[Pure]
public Option<TResult> DownCast<TResult>()
where TResult : TItem
=> _hasItem
? Option.Some((TResult)_item)
: Option<TResult>.None;
[Pure]
public Option<TResult> As<TResult>()
where TResult : class
=> _hasItem
? Option.FromNullable(_item as TResult)
: Option<TResult>.None;
}
Proposal:
Only implement the As function and only on Option
Reasons:
The upcast idea looks really cool 😍
I think we might be able to extend that to Either and Result as upcasts are infallible, right?
public static class UpCast<TResult>
where TResult : notnull
{
public static Option<TResult> From<TItem>(Option<TItem> option)
where TItem : notnull, TResult
=> throw new NotImplementedException();
public static Either<TLeft, TResult> From<TLeft, TRight>(Either<TLeft, TRight> either)
where TLeft : notnull
where TRight : notnull, TResult
=> throw new NotImplementedException();
// Same thing for Result
}
Yes the UpCast cannot fail since we do type check statically.
I reviewed the implementation it's merged.
I run into problems in which a DownCast would be helpful more often, thats why I tried to find an acceptable solution.
I propose a solution for DownCast<T>
which looks very similar to UpCast<T>
and works for Option
, Either
and Result
.
PR #794
The alternatives currently:
Functional.Identity
cannot be used because of the differing return type.Option<T>
co-variant, this case would be a non-issue.