Giter Site home page Giter Site logo

csharpfunctionalextensions's People

Contributors

a-z-hub avatar benprime avatar bopazyn avatar caleb9 avatar fliebrecht avatar golavr avatar hankovich avatar julienasp avatar jvssd avatar kasamviesselman avatar linkdotnet avatar marcelroozekrans avatar mikelthief avatar mingazhev avatar mnissl avatar prophetlamb avatar razenpok avatar rutkowskit avatar samuelviesselman avatar seangwright avatar sergatgh avatar solvingj avatar space-alien avatar svhankovich avatar svroonland avatar tinytownsoftware avatar vkhorikov avatar xavierjohn avatar yaevh avatar yudatc2i avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csharpfunctionalextensions's Issues

typed fail excepion

Is it possible to create an additional overload for typed failed exceptions? As far as I can see, only an error-message is supported. But the type of exception is for example easy for unit-testing :)

cheers!

Proposal: Add implicit operator T(Maybe<T> value)

I think it would be nice to be able to implicitly convert Maybe<T> to T.
By adding this piece of code to Maybe<T>:

public static implicit operator T(Maybe<T> maybe)
{
	return maybe._value;
} 

it will be possible to do something like this:


Maybe<int> maybe = 666;	
int value = maybe;	
int result = value + maybe + value;

It will also allow passing directly Maybe to functions with T parameter.

Name collisions

Hi Vladimir,

Currently I am trying to use your CSharpFunctionalExtensions library, but I am getting a name collision when I try to use it as follows.

// Given a function with a signature of Func<string, bool>.
bool IsNotNullOrWhiteSpace(string text) => !string.IsNullOrWhiteSpace(text);

// When I try to use Ensure like this.
// Then the compiler gives a error.
void MyFunction(string text) {
  Result.Ok(text)
    .Ensure(IsNotNullOrWhiteSpace, "Text is null or white space.")
}

Compiler warning:

The call is ambiguous between the following methods or properties:
'AsyncResultExtensionsRightOperand.Ensure(Result, Func<T, Task>, string)'
and
'ResultExtensions.Ensure(Result, Func<T, bool>, string)'

// This is possible:
void MyWorkAround(string text) {
  Result.Ok(text)
    .Ensure(t => IsNotNullOrWhiteSpace(t), "Text is null or white space.")
}

It is not a problem, though I prefer the cleaner look of just using the name of my expression bodied function.

I would prefer prefixing async functions with Async to explicitly state their nature and moving them to their own namespace.

If you do not have any objections I could create a pull request unless this behavior is by design?

P.S.
I really enjoyed your PluralSight course and I am looking forward to seeing more from you in the future.

Error : Cannot implicitly convert type

The following code:

IEnumerable<string> list = new List<string>();
Maybe<IEnumerable<string>> maybeList = list;  // line in error

gives me the error

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'CSharpFunctionalExtensions.Maybe<System.Collections.Generic.IEnumerable>'

Instead, the following code, works perfectly:

List<string> list = new List<string>();
Maybe<IEnumerable<string>> maybeList = list;

Any hint?

Make error message separator , configureable

We use this library in our project but we have one suggestion. It would be cool if it is able to configure the error message separator which is now the constant ", " on one central point.

For example:

Result.SetupErrorMessageSeparator("$$");

I know, it is able to pass the error message separator on method level like

Result.Combine("$$", r1, r2);

But this is not a solution for us because then we have to pass the separator on each usage of combine.

Do you see a opportunity to implement this?

Question about Maybe and Enums

I think I just determined that Maybe can't be used to hold enum's because it can currently only hold reference types, is this correct?

If so, I think it's because you've constrained T to "class" specifically.

public struct Maybe<T> : IEquatable<Maybe<T>> where T : class

Can you think of any easy way to achieve an enum type in a Maybe?

For the record, I was trying to implement text parsing adapters for enums and other primitive types into Maybe's. The goal was similar to what was achieved here:

https://github.com/louthy/language-ext

If you scroll down, you can see how they replaced TryParse with parseInt that returns an option.

Interestingly, they did not do am implementation for parseEnum, but in theory they could have.

Extension resolution

This works:

private IObservable<Unit> MyMethod() => MyApi
            .DoSomething()
            .Select(result => ResultExtensions
                .OnSuccess(result, () => { _myVariable = result.Value; })
                .OnSuccess(() => NavigationService.GoBack())
                .OnFailure(async error => await NavigationService.DisplayAlert(error))
                .OnBoth(_ => Unit.Default));

this doesn't:

private IObservable<Unit> MyMethod() => MyApi
            .DoSomething()
            .Select(result => result
                .OnSuccess(() => { _myVariable = result.Value; })
                .OnSuccess(() => NavigationService.GoBack())
                .OnFailure(async error => await NavigationService.DisplayAlert(error))
                .OnBoth(_ => Unit.Default));

On the one that fails, R# complains that the first OnSuccess is missing a return statement;
Note that even on the first version I have to add ugly braces otherwise it thinks my Action is a Func.

Result desconstruction

I want to propose the feature of deconstructing Result, so we can do

var (isSuccess, isFailure, error) = Result.Ok();
var (isSuccess, isFailure, somethingIsDisabled, error) = Result.Ok(true);

Motivation for me is the case when you have a primitive value, like bool wrapped in Result and we want to leave the monad e.g.

var serviceIsDisabled = CheckIfDisabled()

if (serviceIsDisabled.Value) // Do something

serviceIsDisabled.Value in condition looks kinda ugly to me, so i've implemented deconstruction via extension methods. It would be nice to have it in the main package.

Please, let me know if you're ok with and i'll prepare PR with tests and stuff

Json serialization of Result

I can't return Result from a webapi as in case of success, Error throws an exception of type 'System.InvalidOperationException'. Why not just return string.empty?

Cannot Access Maybe<T>.None on .NET 4.6.2

Hello,

I am using your library within a .NET 4.6.2 project and cannot access the Maybe.None static property.

The following does not compile (error is: 'Maybe' does not contain a definition for 'None'):
Maybe<MyClass> none = Maybe<MyClass>.None;

But this does:
Maybe<MyClass> none = null;

What's going on here?

Thanks,
Greg Valainis

1.8.0+ Breaks at least one Ensure Overload

The following worked on 1.7.1 but I just updated to 1.8.1 and now it fails to match the appropriate overload on ensure.

Here was my original code:

            return GetAuthenticationContext(authority)
                .OnSuccess(context => AcquireTokenAsync(context, resource))
                .Ensure(authResult => authResult != null, "Failed to Obtain JWT")
                .Map(authResult => authResult.AccessToken)
                .Result.Value;

AcquireTokenAsync() returns Task<Result<T>>

Heres the overload it used to match in AsyncResultExtensionsLeftOperands.cs

        public static async Task<Result<T>> Ensure<T>(this Task<Result<T>> resultTask, Func<T, bool> predicate, string errorMessage)
        {
            Result<T> result = await resultTask;

            if (result.IsFailure)
                return Result.Fail<T>(result.Error);

            if (! predicate(result.Value))
                return Result.Fail<T>(errorMessage);

            return Result.Ok(result.Value);
        }

My guess is that it's related to the new param bool continueOnCapturedContext = false, but in theory the default parameter should have maintained backward compatibility... so I don't know what the deal is. If I find time, I'll try to write a new test and troubleshoot.

How to share value between successive calls in the pipeline

I have following method:

public async Task<Result<MyOrderModel>> GetMyOrderByOrderId(string subject, long orderId)
        {
            long customerId = 0;

            Action<Customer> keepCustomerId = (c) => customerId = c.Id;

            return await GetCustomerBySubjectAsync(subject)
               .ToResult(ErrorMessage.CustomerNotFound)
               .OnSuccess(customer => keepCustomerId(customer))
               .OnSuccess(customer => GetOrderByIdAsync(orderId).ToResult(ErrorMessage.OrderNotFound))
               .Ensure(order => order.Customer.Id == customerId, ErrorMessage.AmbigiousPrincipalCall)
               .OnSuccess(order => _mapper.Map<MyOrderModel>(order));
        }
  public async Task<Maybe<Customer>> GetCustomerBySubjectAsync(string sub)
        {
            return await _context.Customers.Where(c => c.Sub == sub).FirstOrDefaultAsync();
        }

In the Ensure statement I need access to a result of GetCustomerBySubjectAsync.
For that reason I'm storing customerId in the very first OnSuccess method.

I'm sure there is a more elegant way?
Thanks in advance.

ResultExtensions, why Ensure creates new instance of Result?

Hi, is there a reason that Ensure method creates a new instances of result?
We can just return current result object if current result.IsFailure.

` public static Result Ensure(this Result result, Func<T, bool> predicate, string errorMessage)
{
if (result.IsFailure)
return Result.Fail(result.Error);

        if (!predicate(result.Value))
            return Result.Fail<T>(errorMessage);

        return Result.Ok(result.Value);
    }`

Result with Task Cancellation

Hi Vladimir,

I really enjoyed your PluralSight course and I really appreciate the thoughts which went into this library.
However, I am not entirely sure how to use the Result struct together with a cancelable task (e.g if I have a method, that returns a Task<Result>).
How would you handle the task cancellation? Returning an error result seems to be somehow wrong. I also though about returning a Result<Maybe>

Nuget Package Code Installation

There is some project I cannot use dll file. (Such as Dynamics CRM Plugin)

In this case, source installation is really helpful (like as DryIoC and DryIoC.dll nuget pacakge)

Could you provide source installation Nuget Package?

How using OnSuccess/OnFailure inside an linq aggregate function

var totalCost = Orders.Sum(s =>
                {
                    return OperationOnOrder(s)
                        .OnBoth(r => r.IsSuccess ? r.Value.Cost: 0)
                        ;
                });

So OperationOnOrder returns

Result<SomethingElse>

Now, the problem is that I can not "jump out" when OperationOnOrder returns failure, I can only return a decimal value (which sum can handle), so what I do this return 0, but I want to return failure rather than 0.

Any suggestion?

Result with error type

Hey guys,
First of all a very usefull library :) .

  1. When using error types (Result<int, SomeType> ) in an Onsuccess method that is calling an async method, the resulting Result is wrapped in another Result

Example

Task<Result<int,ErrorType>> GetSomething(){ ... }

var theResult= await Result.Ok().OnSuccess( () => GetSomething());

theResult will be of type Result<Result<int,ErrorType>>

If the example is not clear, please let me know and I will create a test project

I suppose that the methods in AsyncResultExtensionsRightOperand need to be extended

It would be nice to be able to use an error object without the need to also have a return type for value. Maybe an interface needs to be introduced

Install failed - could not install package ... into a project that targets '.NETFramework,Version=v4.0'

Trying to install the package into .NET 4.0 project, but it fails. Is .NET 4.0 not supported or is something else going wrong?

Error:

Install failed. Rolling back...
Install-Package : Could not install package 'CSharpFunctionalExtensions 1.7.1'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.0', but the package does not contain any assembly references or content files that are
 compatible with that framework. For more information, contact the package author.
At line:1 char:16
+ Install-Package <<<<  CSharpFunctionalExtensions
    + CategoryInfo          : NotSpecified: (:) [Install-Package], InvalidOperationException
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand
 
PM> 

Adding an implicit operator for T to the Result<T> class to get the value?

I was wondering if this would be a good addition to the Result<T> class:

public static implicit operator T(Result<T> result) { return result.Value; }

The benefits of this implicit operator removes the need for doing result.Value in many places. For example:

public TestClass()
{
            var result = Result.Ok(new Foo());
            //instead of: Foo foo = result.Value
            Foo foo = result;

            //instead of: MethodThatTakesFoo(result.Value)
            MethodThatTakesFoo(result);
}
public void MethodThatTakesFoo(Foo value)  { }

The other benefit is you could rename your var names:

//instead of: var userOrError = ...
var user = userRepository.GetUser(id);
if(user.IsFailure) { }
//Do stuff to the user
//instead of: userRepository.UpdateUser(userOrError.Value);
userRepository.UpdateUser(user);

I've noticed I find myself passing the result into other methods and forgetting the .Value (which obviously causes a compile error). Also, I'm not a big fan of the name "Value", as it is a little too generic and adds a bit of clutter in my opinion. I'm curious about your thoughts on this change. What would be the potential issues/drawback with doing this approach?

Thanks

How can I distinguish between types of failures with Result?

I am using the ResultExtensions in a web API project. No matter what type of error happens in the railway oriented series of calls I am returning 400 (Bad Request). This is convenient and sufficient for now. Here is an excerpt of the code:

[Route("api/qrs/asbuilt/serialnumberstructure")]
[HttpPost]
public IHttpActionResult Post([FromBody] StructureRequestDto structureRequestDto)
{
    return
        ValidateRequest(structureRequestDto)
            .OnSuccess(request => AddNextSerialNumberIfMissing(request))
            .OnSuccess(request => AddPreviousSerialNumberIfMissing(request))
            .OnSuccess(request => AddStructureIfMissing(request))
            .OnSuccess(request => GetStructure(request))
            .Ensure(response => response.HasValue, FormatStructureNotFoundError(structureRequestDto))
            .Map(response => response.Value)
            .OnBoth(
                    response =>
                    response.IsSuccess ? 
                        this.Ok(response.Value) as IHttpActionResult :
                        this.BadRequest(response.Error) as IHttpActionResult);
}

I would like to improve the accuracy of my responses and return 500 for system errors and 400 when the error is caused by the input data. Because the error is string I'm not sure of a good way to do this. I thought about putting the HTTP status codes into the error strings and then parse at the end. That might work.

Are there any suggestions that would help me to be more specific with my error responses?

Thanks

Maybe.None could be added

I could be wrong, but when I want to instantiate Maybe without value I have to use
new Maybe<SomeType>() syntax.
For convenience reason could Maybe.None static method be added like in some other Maybe libraries?

Best Method to "Peek" Into a Result for Logging

With Java streams we have a passive stream operation called "peek" which passes the elements un-touched to the next operation (lambda should return void):

list
.stream()
.peek(element -> log.info("element = " + element))
.map(element -> element is unscathed)

I haven't seen an equivalent in the library. Does one exist? If not, hard to add? It's like ensure but returns void rather than bool?

Need help choosing Result or Maybe

I am using the extensions for a method that gets some data from another system.

The 3 possible results of calling this method are:

  1. The data is found and returned.
  2. No data is found for the given parameter values but the connection and query worked.
  3. The database connection and/or query failed for some unexpected reason so we don't know if the data exists or not.

If I use Maybe I can handle case 1 and 2 but case 3 is not expressed in the signature.

If I use Result I can handle 1 and 3 but I'm not sure how to handle case 2.

I guess it is possible to use Result<Maybe<DataObject>>. Is that the best option?

What are the guidelines for choosing Maybe versus Result?

Thanks,

Matthew

Result Try method

I'm using your Result object with a third-party library that communicates using exceptions. I'd like to lift the exceptions into a failed Result. My current code just returns a different Result from each branch of the try-catch.

I'm thinking something like:

Result.Try(() => library.ThingThatMightFail(),
           (ex) => "Some error message, possibly branching on exception type...");

// Where
Try<Result<T>>(Func<T> attempt, Func<Exception,string> failure)

Handling specific exceptions can be done with ex is SomeException, and truly unexpected exceptions can be rethrown.

This would just be a convenience method, but often the reason I'm using a Result is to hide library exceptions behind more user friendly error messages.

Result.Combine does not work with Result<T>[]

Pretty clear issue here, just needs an overload.

Result[] test1 = new Result[] { Result.Ok("one") };

Result.Combine(test1);
//Throws "Argument 1: cannot convert from 'CSharpFunctionalExtensions.Result[] to 'string'"

Result.Combine("dummy", test1);
//Throws "Argument 2: cannot convert from 'CSharpFunctionalExtensions.Result[] to 'CSharpFunctionalExtensions.Result'"

Add extension method Combine for IEnumerable<Result<T>> / IEnumerable<Result>

In case OnSuccess return IEnumerable<Result> required to use method:

var result = Result.Combine(results);
return result.IsSuccess
         ? Result.Ok(results.Select(e => e.Value))
         : Result.Fail<IEnumerable<T>>(result.Error);

and to do it in OnSuccess method:
.OnSuccess(results => /*code above*/)

It will be nice to have extension methods:
Result<IEnumerable<T>> Combine(this IEnumerable<Result<T>> results)
Result Combine(this IEnumerable<Result> results)

In this case we will have something like:

.OnSuccess(arg => ... ) /* returns IEnumerable<Result<T>> */
.Combine() /* convert IEnumerable<Result<T>> to Result<IEnumerable<T>> */
.OnSuccess(collection => ... )

Help with naming extension method that executes some function and returns Result<T> if success

I'm writing an extension method that operates over a collection and executes some operation. It doesn't care about the output of that function, rather it returns back the original collection if the operation succeeds, else it returns a Result.Fail (and the error msg of the action) if it fails.

So instead of doing

DoSomething()
  .OnSuccess(x => x.DoSomethingElse())
  .OnSuccess(x => {
    DoSomethingElse2()
    return x
  })
  .OnSuccess(x => x.DoSomethingElse3())

I'd do something like

DoSomething()
  .OnSuccess(x => x.DoSomethingElse())
  .OnSuccess(x => x.Execute(() => DoSomethingElse2()))
  .OnSuccess(x => x.DoSomethingElse3())

Where Execute is a generic function defined as

public static Result<T> Execute<T>(this T collection, Func<Result> fn)
   where T : IEnumerable
{
   Result res = fn();
   return res.IsSuccess
      ? Result.Ok(collection)
      : Result.Fail<T>(res.Error);
}

Is Execute an appropriate name in this case? I only care about whether an action method succeeds or not, but I'm never returning the actual results of that function so it seems misleading...how would you name that? Since I'm using your library, I figured I could use your expertise ๐Ÿ˜„

Initializing new Maybe object

First, this is an awesome library!! I have been using it for several days and I love the control flow.

One change I'd like to suggest is to the Maybe module. It works great if you want to expose a Maybe as a property. But I'd like to be able to create a new Maybe object and pass it on.

For example, an error occurs and I just want to ignore it and return a Maybe. Currently, it seems like you have to create a new variable and return it. This is a little ugly in a lambda.

.OnBoth(result =>
 {
       Maybe<CachedVehicle> ret = result.IsSuccess ? result.Value : null;
       return Result.Ok(ret);
})

I'd prefer to do something like this:

.OnBoth(result => Result.Ok(Maybe<CachedVehicle>(result.IsSuccess ? result.Value : null))

Does that make sense? Did I miss something and maybe this is already possible?

Maybe with Structs

Is there any way to support structs with Maybe?

I removed the 'where T : class' from the code but then I found this issue:

struct Account{
public Guid Id;
}

Maybe<Account> SomeFunction(){
var list = new List<Account>();
return list.FirstOrDefault()
}

var result = SomeFunction();
//This is true!! it should be false
Assert.IsTrue(result.HasValue)

I want to make Account a struct because I need to use use Entity Framework and its use of references (not immutability) is making my life crappy. So I tried to use structs for value passing, but now I can't seem to use Maybe.

Any suggestions you have would be great. Hope I provided enough info.

EqualityComparer for Maybe<Dynamic> returns not equals for Maybe<>.None.

Hi,
I came across this issue while investigating a problem in other open project (NSubstitute). After some ffiddling I think I managed to trace it to the implementation of EqualityComparer for Maybe<>.

They say code is worth 1000 words, so here is the sample :

    [Test]
    public void Bug_MaybeDynamicNone()
    {
        var compareUsingMaybeDynamic = EqualityComparer<Maybe<dynamic>>.Default.Equals(Maybe<dynamic>.None, Maybe<dynamic>.None);
        
        var compareObjectNotDynamic = EqualityComparer<object>.Default.Equals(Maybe<int>.None, Maybe<int>.None);

        var compareDynamicInt = EqualityComparer<object>.Default.Equals((dynamic)1, (dynamic)1);

        //NSubstitute is using object as generic type which doesnt work for Maybe<dynamic>
        var compareUsingMaybeObject = EqualityComparer<object>.Default.Equals(Maybe<dynamic>.None, Maybe<dynamic>.None);

        Assert.IsTrue(compareUsingMaybeDynamic);
        Assert.IsTrue(compareObjectNotDynamic);
        Assert.IsTrue(compareDynamicInt);
        Assert.IsTrue(compareUsingMaybeObject); // Only comparission of Maybe<dynamic>.None using object comparer fails.
    }

    [Test]
    public void Bug_DefaultInstance()
    {
        var compareMaybeIntUsingObject = EqualityComparer<object>.Default.Equals(Activator.CreateInstance(typeof(Maybe<int>)), Activator.CreateInstance(typeof(Maybe<int>)));

        var compareUsingMaybeDynamic = EqualityComparer<Maybe<dynamic>>.Default.Equals(Activator.CreateInstance(typeof(Maybe<dynamic>)), Activator.CreateInstance(typeof(Maybe<dynamic>)));

        //NSubstitute is using object as generic type which doesnt work for Maybe<dynamic>
        var compareMaybeDynamicUsingObject = EqualityComparer<object>.Default.Equals(Activator.CreateInstance(typeof(Maybe<dynamic>)), Activator.CreateInstance(typeof(Maybe<dynamic>)));

        Assert.IsTrue(compareMaybeIntUsingObject);
        Assert.IsTrue(compareUsingMaybeDynamic); // Surprisingly this one fails for Default instance but not for Maybe<>.None
        Assert.IsTrue(compareMaybeDynamicUsingObject); //Here is the same problem as with Maybe<dynamic>.None in the test above 
    }

I hope this will be enough to reproduce it. In case you need any more information let me know.

Regards
K.

Edit:
I found even simpler repro

var equals = Maybe<dynamic>.None == (dynamic)Maybe<dynamic>.None;
Assert.True(equals);

also found where the problem is Line 71 in Maybe<>

if (obj is T)
{
    obj = new Maybe<T>((T)obj);
}

This check will pass for dynamic and will create new object with value in it which will fail down the line since current object HasNoValue while the newly created one Has.

Edit 2:
Actually
Maybe<dynamic>.None == (dynamic)Maybe<dynamic>.None;
Is a problem with Implicit conversion while my problems were in Equals.
Changing line 71 to
if (obj is T && !(obj is Maybe<T>))
fixes my problem but doesnt fix implicit conversion bug. I tried to find something to make also this one go away, but only thing I found was an infinite implicit conversion :)

Thats all I've got :) Hope this helps.

K.

Is there a "flatMap" method in the library?

I searched the repo and found no reference to flatMap, but perhaps Map is overloaded with similar functionality or something. Can you please clarify?

I am running into scenarios like this and perhaps flatMap would be the typical functional solution.

FirstTask()
.Map(inputObject => CreateSomeResultOfClient(inputObject))
.Map(client => client.DoSomething()) <----Doesn't work because client is Result
.OnSuccess(string => Console.WriteLine(string));
.OnFailure(error => Console.WriteLine(error));

Maybe<DateTime> doesn't work

Hi!

I'm trying to have optional DateTime. But when I do Maybe<DateTime>.None, it uses the default value which is 0001-01-01, and when I do .HasValue, it's true.

Thanks !

Func<T> to Result<T>

Hi! I have a personal project with a class similar to Result<T> and I have the following method, which is used to wrap code on Result structure.

I am planning to submit a PR for this. What do you think?

Code

public static Result<T> ToResult<T>(this Func<T> func)
{
    try
    {
       return Result.Ok(func());
    }
    catch (Exception ex)
    {
       return Result.Fail<T>(ex.Message);
    }
}

Usage

public Result<TDTO> GetById(TKey key) 
{
    return Result.ToResult(() => ToDTO(Repository.GetById(key)));
}

Suggestion: tag versions

I'm trying to see what has changed between the 1.7.1 and 1.8.0 nuget package versions. Tagging the versions would help with that considerably.

default ConfigureAwait(false) is causing to lose thread culture

I have a heavy usage of your functional library, it is doing a great job as part of API project. The problem I noticed is that after calling OnSuccess or ToResult on async methods current thread culture is lost because you are using ConfigureAwait(false) as default which doesn't return to thread caller, but to first available thread. I know OnSuccess and ToResult have parameter bool continueOnCapturedContext = false that I can set to true, but I wouldn't want to do this on every place in code. So my question actually is, why do you have ConfigureAwait(false) in your library when .NET is continuing on captured context ( ConfigureAwait(true) ) by default? And is it possible that you set continueOnCapturedContext to have default value = true?

Result - How to handle async methods in the middle of a chain when the chain doesn't begin with an async method

For example the following test doesn't compile

public async Task<string> Promote_with_async_methods_in_the_middle_of_the_chain_but_not_starting_the_chain(long id)
{
	var gateway = new EmailGateway();

	// GetById rather than GetByIdAsync
	return await GetById(id)
		.ToResult("Customer with such Id is not found: " + id)
		.Ensure(customer => customer.CanBePromoted(), "The customer has the highest status possible")
		.OnSuccess(customer => customer.PromoteAsync())
		.OnSuccess(customer => gateway.SendPromotionNotificationAsync(customer.Email))
		.OnBoth(result => result.IsSuccess ? "Ok" : result.Error);
}

Strong Name

Is it possible to strong name the assemblies?

Many Thanks

Maybe<int>.None.HasValue is true

While tracking a bug if found that Maybe.None.HasValue was true whereas my expected behavior is that any None would have no values.

Maybe.None doesn't work with Tuples

Contrary to what I expected, Maybe<(ClassA, ClassB)>.None.Hasvalue is true.

It's more an information than an issue and surely I could try a PR to support tuples but tought it'd be good to mention it somehwhere.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.