-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intended usage when calling method that itself return a OneOf<T> #145
Comments
You can try the Bind ext method. public record Result(string Name, int Age, Guid Id);
public class Parser
{
public OneOf<Result, Exception> Parse()
{
return GetName()
.Combind(GetAge())
.Combind2(GetId())
.MapT0(_ => new Result(_.Item1, _.Item2, _.Item3));
}
private OneOf<string, Exception> GetName() => "Value1";
private OneOf<int, Exception> GetAge() => 123;
private OneOf<Guid, Exception> GetId() => Guid.NewGuid();
}
public static class Ext
{
public static OneOf<(T1, T2), E> Combind<T1, T2, E>(this OneOf<T1, E> opt1, OneOf<T2, E> opt2)
=> opt1.Match(
t1 => opt2.Match(
t2 => OneOf<(T1, T2), E>.FromT0((t1, t2)),
e => e
),
e => e
);
public static OneOf<(T1, T2, T3), E> Combind2<T1, T2, T3, E>(this OneOf<(T1, T2), E> opt1, OneOf<T3, E> opt2)
=> opt1.Combind(opt2).MapT0(_ => (_.Item1.Item1, _.Item1.Item2, _.Item2));
} |
@BADF00D, enter the monad! #r "nuget: OneOf, 3.0.243"
using OneOf;
public class Parser
{
public OneOf<Result, Exception> Parse() =>
GetName()
.AsBindable()
.Bind(name => new Result(name).AsBindable())
.Bind(result => GetAge().AsBindable().Bind(age => (result with { Age = age }).AsBindable()))
.Bind(result => GetId().AsBindable().Bind(id => (result with { Id = id }).AsBindable()))
.Result();
private OneOf<string, Exception> GetName() => "Value1";
private OneOf<int, Exception> GetAge() => 123;
private OneOf<Guid, Exception> GetId() => Guid.NewGuid();
}
// Monad
public class Maybe<TA> where TA: notnull
{
private OneOf<TA, Exception> value;
private Maybe(Exception ex) => value = ex;
public Maybe(TA someValue) => value = someValue;
public Maybe(OneOf<TA, Exception> value) => this.value = value;
public Maybe<TB> Bind<TB>(Func<TA, Maybe<TB>> f) where TB : notnull
=> value.Match(
taValue => f(taValue),
ex => Maybe<TB>.Exception(ex));
public static Maybe<TA> Exception(Exception ex) => new Maybe<TA>(ex);
public OneOf<TA, Exception> Result() => value;
}
// Extension methods
public static Maybe<TA> AsBindable<TA>(this TA value) where TA : notnull
=> new Maybe<TA>(value);
public static Maybe<TA> AsBindable<TA>(this OneOf<TA, Exception> oneof) where TA : notnull
=> new Maybe<TA>(oneof); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm new to this library and not quite sure if I use it the right way.
Imagine I want to write a little Parser, that returns a record of type
Result
. Each property is parsed by invoking a method that can parse this property or returns an exception. How would I write the Parse method, that collects the values from the methods?My current solution looks like the following:
Is there a better, more readable way to write the
Parse
method?The text was updated successfully, but these errors were encountered: