首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c# LanguageExt中将Either<Error、Option<X>>转换为Option<Either<Error、X>>

在c# LanguageExt中将Either<Error、Option<X>>转换为Option<Either<Error、X>>
EN

Stack Overflow用户
提问于 2020-03-05 19:09:32
回答 1查看 482关注 0票数 0

我正在使用C# LanguageExt https://github.com/louthy/language-ext

我有一个从一些Json中解析出来的类MyDto。解析函数返回Either<Error, Mydto>。如果dto与给定的规则匹配,或者它是一个错误,那么我希望返回结果,否则,什么也得不到。

最后的结果应该是Option<Either<Error, Mydto>>类型。

我最终得到了像这样的东西

代码语言:javascript
复制
Option<Either<Error, MyDto>> finalResult =  
     MyDto.From("some json") // Returns Either<Error, MyDto>
          .Right(dto => (dto.Equals("something")
             ? Some<Either<Error, IDhResponse>>(Right(dto))
             : None))
          .Left(error => Some<Either<Error, IDhResponse>>(Left(error)));

我真的不喜欢它,因为它呈现了太多的重复。

然后我尝试了这个

代码语言:javascript
复制
MyDto.From("some json") // Returns Either<Error, MyDto>
   .Map(dto => dto.Equals("something")
      ? Some(dto)
      : None)

但它返回的Either<Error, Option<MyDto>>看起来还不错,如果在这一点上我可以带出选项的话。不幸的是,我找不到任何可以做到这一点的东西。

有什么东西存在吗?或者有更好的方法去做我想做的事情?

也许是像这样的

代码语言:javascript
复制
 MyDto.From("some json") // Returns Either<Error, MyDto>
   .Where(dto => dto.Equals("something")) // Only applies to Right branch and wrap everything in  Option when fails

谢谢你在这方面的建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-07 00:07:37

好的,这里有三个代码解决方案:

代码语言:javascript
复制
Either<Exception, int> resultOfParsing = Right(10); // Left(new Exception("error"))

// version 1: make use of "bottom" state:
Either<Exception, int> filterResultUsingBottom = resultOfParsing.Filter(i => i > 5);

var textResultUsingBottom = filterResultUsingBottom.Match(i => $"success: {i}", exception => $"error: {exception.Message}", () => "condition: false");

// version 2: inner option
Either<Exception, Option<int>> filterResultInnerOption = resultOfParsing
    .Map(i => Some(i))
    .FilterT(i => i > 5);

var textResultInnerOption = filterResultInnerOption.Match(noError =>
        noError.Match(i => $"success: {i}", () => "condition: false"),
    exception => $"error: {exception.Message}");

// version 3: outer option
Option<Either<Exception, int>> filterResultOuterOption = filterResultInnerOption.Sequence();

var textResultOuterOption = filterResultOuterOption.Match(noConditionFail =>
        noConditionFail.Match(i => $"success: {i}", exception => $"error: {exception.Message}"),
    () => "condition: false");

正如你所看到的,所有版本都可以以类似的方式使用(Match行)。您应该根据您希望在程序中拥有/传递的类型来选择所需的版本。

如果你不太关心“条件失败”和“异常”之间的区别,那么版本1(底部)可能是可以的(避免类型嵌套)。但我个人更喜欢后一种解决方案。您可以使用.Sequence()按需在它们之间进行切换。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60544031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档