如何使用 LanguageExt EitherAsync 返回 Left 的非错误类型?

2024-01-06

我有一个方法,可以在数据库中查找会员卡,如果找到并且有效则返回它,或者返回enum值,如果没有。这允许调用代码打开enum价值。我想退货Either<TransactionRequestStates, Card>,因为该方法将与几个用于获取和验证传入数据的类似方法绑定在一起。由于应该进行数据库调用async,我需要返回EitherAsync而不是仅仅Either.

为了澄清这一点,我有几种方法,每种方法都执行一个特定的步骤。如果成功,每个方法都会返回一个Right包含稍后方法使用的一些数据。如果不是,则返回一个Leftenum值表明出了什么问题。我想将它们组成如下(为了清楚起见,进行了简化)...

public static async Task<TransactionRequestStates> Process(
        IHttpContextAccessor httpContextAccessor,
        AppDbContext context, UserManager<User> userMgr,
        string cardSerialNumber, string uri, int amount, string hash) {
  Either<TransactionRequestStates, TransactionRequestStates> result = await (
    from card in GetCard(context, cardSerialNumber, amount)
    from deviceSerialNumber in GetDeviceSerialNumberFromToken(httpContextAccessor, context, userMgr)
    from device in GetDevice(httpContextAccessor, context, deviceSerialNumber)
    from rental in GetOrganisationRental(context, device)
    from vcResponse in GetVcResponse(rental, card, amount, hash, uri)
    from saveResponse in SaveResponse()
    select TransactionRequestStates.Success
  );
  return result.Match(_ => TransactionRequestStates.Success, msg => msg);
}

这个问题涵盖了GetCard方法,因为我假设如果我能做到这一点,其他人都会遵循类似的模式。

我可以执行以下操作...

  private static EitherAsync<TransactionRequestStates, Card> GetCard(AppDbContext context, string cardSerialNumber) {
    Card? card = context.Cards.SingleOrDefault(c => c.SerialNumber == cardSerialNumber);
    if (card == null) {
      return TransactionRequestStates.CardNotFound.AsTask();
    }
    if (card.Locked) {
      return TransactionRequestStates.CardLocked.AsTask();
    }
    // Quite a few more checks are done in the real code. If we pass them all, return the card...
    return card.AsTask();
  }

然而,这都是同步代码。我希望数据库调用是异步的。根据我从 Guru Stron 那里得到的答案上一个问题 https://stackoverflow.com/a/72901808/706346,我知道我可以做这样的事情......

static EitherAsync<string, int> Square2(int n) =>
    TryAsync(async () =>
        {
            await Task.Delay(300);
            throw new Exception();
            return n * n;
        })
        .ToEither(error => error.Message);

但是,我不想返回string如果出现异常,我想返回一个enum值,如上图所示。

我不知道该怎么做。如果我尝试返回enum直接值...

  private static EitherAsync<TransactionRequestStates, Card> GetCard2(AppDbContext context, string cardSerialNumber) =>
    TryAsync(async () => {
      Card? card = await context.Cards.SingleOrDefaultAsync(c => c.SerialNumber == cardSerialNumber);
      if (card == null) {
        return TransactionRequestStates.CardNotFound.AsTask();
      }
      if (card.Locked) {
        return TransactionRequestStates.CardLocked.AsTask();
      }
      return card;
    });

...然后我收到编译器错误“无法从用法中推断出方法“Prelude.TryAsync(Func)”的类型参数。尝试显式指定类型参数“。我对此类错误的经验表明我的代码是错误的,就好像它是正确的一样,编译器应该能够推断出类型。

我尝试返回Left<TransactionRequestStates, Card>(TransactionRequestStates.CardNotFound)(有或没有打电话AsTask()最后),但这并没有改变错误。我还尝试将呼叫添加到ToEither()最后,但这也没有帮助。

任何人都能够解释我需要做什么才能返回EitherAsync<TransactionRequestStates, Card>? Thanks


为什么让事情变得如此困难?

一堆单子就像EitherAsync主要存在是因为它本身就是一个monad https://blog.ploeh.dk/2022/03/28/monads,因此定义了一个SelectMany提供查询语法(语法糖)的方法。如果您需要组合多个,这非常有用EitherAsync彼此的价值观。这里的情况并非如此。

将方法定义为返回会更容易Task<Either<L, R>>,因为这样你就可以依赖 C# 原生async and await功能。您可以随时使用ToAsync https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Value%20Monads/Either/Either/index.html#Either_2_ToAsync_0 and ToEither https://louthy.github.io/language-ext/LanguageExt.Core/Monads/Alternative%20Value%20Monads/Either/EitherAsync/index.html#EitherAsync_2_ToEither_0如果您(在方法实现内部)需要来回转换EitherAsync功能。

如果你这样做,你可以公平地使用惯用语 https://blog.ploeh.dk/2015/08/03/idiomatic-or-idiosyncraticC# 实现所需的功能:

public static async Task<Either<TransactionRequestStates, Card>> GetCard(
    AppDbContext context,
    string cardSerialNumber)
{
    Card? card = await context.Cards.SingleOrDefaultAsync(
        c => c.SerialNumber == cardSerialNumber);
    if (card == null)
        return Left<TransactionRequestStates, Card>(
            TransactionRequestStates.CardNotFound);
    if (card.Locked)
        return Left<TransactionRequestStates, Card>(
            TransactionRequestStates.CardLocked);

    return Right<TransactionRequestStates, Card>(card);
}

如果你想将其转换为EitherAsync你可以轻松做到这一点:

public static EitherAsync<TransactionRequestStates, Card> GetCard2(
    AppDbContext context, string cardSerialNumber) =>
    GetCard(context, cardSerialNumber).ToAsync();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 LanguageExt EitherAsync 返回 Left 的非错误类型? 的相关文章

  • 用于清理 openssl EVP_PKEY 私钥内存的 C 代码

    我开始学习 C C 中的 OpenSSL 编程 我遇到的一个问题是 如何安全地清除私钥的内存 例如 我可能有代码 EVP PKEY private key PEM read bio PrivateKey bio RSA r EVP PKEY
  • "/>

    Error 5 expected Css test css gt gt 我需要给吗 在这里 因为我的解决方案仍然无法正常工作 它开始给出一些其他错误 您需要添加一个等号 如下所示 Css test css gt gt 解释 块将整个语句或块
  • CMake source_group() 无法在分层项目设置中正常工作

    在进行更改以使 CMake 项目具有分层文件夹管理后 source group 似乎不再正常工作 CMake 只是将所有内容转储到默认过滤器中 我尝试了各种正则表达式来从父级获取每个源文件的相对文件路径 甚至对父级 CMakeLists t
  • 使用MVVM Light的Messenger在视图模型之间传递值

    有人可以帮我解释一下 MVVM Light 的 Messenger 吗 我正在阅读 StackOverflow 上的一篇文章 MVVM 在视图模型之间传递值 https stackoverflow com questions 6392854
  • 使用 Protobuf-net 序列化 object[]

    我想序列化和反序列化存储在对象数组中的一些值 public class Sample public object Data 我知道在运行时数组中期望什么类型 实际上 我想将 Sample 内部的数据视为消息流 就个人而言 我知道我可以使用S
  • 如何在 RestSharp 中使用 PUT?

    我想使用 PUT 但我只能找到如何使用 POST 的示例 我要发送的json数据是使用这个cURL命令发送的curl i H Content Type application json X PUT d status 1 http 192 1
  • CSV 提供的数据源第一列中存在奇数字符

    我有一个 CSV 文件 已添加到 Visual Studio 单元测试项目中 它有七列 如下所示 assessmentitemid reviewer1 reviewer2 reviewer3 reviewer4 reviewer5 revi
  • if constexpr 与 sfinae

    随着引入if constexpr in c 17 通过使用编译时 SFINAE 解决了一些问题c 14 c 11现在可以使用解决if constexpr 具有更简单的语法 例如 考虑以下编译时递归的基本示例 以生成打印可变数量参数的子例程
  • `uint_fast32_t` 保证至少与 `int` 一样宽吗?

    C 标准规定整数操作数小于int将晋升为int在对它们执行任何算术运算之前 因此 对两个小于的无符号值进行运算int将使用有符号而不是无符号的数学来执行 如果需要确保使用无符号数学对 32 位操作数执行操作 例如 将两个乘积可能超过 2 的
  • C语言中的积分提升和平衡有什么区别?

    积分提升和平衡有什么区别 我们是否可以总结这两条规则 即在执行任何操作 逻辑运算符 除外 之前 任何类型都至少转换为 int 或 unsigned int 类型 如果任何操作数的类型为更大 则转换为更大的类型比整数 积分促销 是旧的C90术
  • 如何doxygen注释Qt属性?

    我想将 Doxygen 注释附加到我的 Q PROPERTY 例如 song h class Song public QObject Q OBJECT private Q PROPERTY QString title READ title
  • C - 具有可变数量参数和命令行参数的函数

    我需要排序n按字典顺序排列的作为参数数量可变的函数的参数的字符串数量 在main函数中 字符串被读取为命令行参数 这是我的代码 include
  • 如何在 Unix 控制台或 Mac 终端中编译和运行 C/C++ 代码?

    如何在 Unix 控制台或 Mac 终端中编译 运行 C 或 C 代码 如果是一个简单的单源程序 make foo 源文件在哪里foo c foo cpp等等 你甚至不需要 makefile Make 有足够的内置规则将源文件构建为同名的可
  • 状态代码:404,原因短语:“未找到”,版本:1.1,

    我使用 Web api 自托管 public class TestController ApiController HttpPost public void Testp FromBody string title Console Write
  • 将 CollectionBase 转换为 List 或可用于 Linq 的数据类型

    我正在使用 Aspose 单元格来操作 Excel 电子表格 API 中的类型之一是电子表格中的图片集合 它派生自 CollectionBase 请参阅此链接 http www aspose com documentation net co
  • 关于捕获异常的良好实践

    我正在用 C 11 编写一个小程序 并且第一次真正使用异常 我有一个关于如何有效捕获异常的问题 经过一番谷歌搜索后我仍然没有答案 这是问题 通过 const 左值引用捕获异常还是通过 const 右值引用捕获异常 哪个更有效 或推荐 在代码
  • static_assert 有什么作用,你会用它做什么?

    你能举个例子吗static assert C 11 会优雅地解决手头的问题吗 我熟悉运行时assert 我应该选择什么时候static assert 超过常规assert 另外 在boost有一种东西叫做BOOST STATIC ASSER
  • 如何使用 C# 和 IBM Watson SDK 将实时音频流立即发送到 IBM Watson Speech-To-Text,而不在本地保存音频文件?

    我需要使用 IBM Watson SDK 使用麦克风录制音频 并使用 C 将其发送到 IBM Watson 语音转文本 我可以通过在本地保存音频文件然后使用发送它来实现此功能NAudio图书馆 但我的要求是使用流模式将实时音频发送到 IBM
  • Nunit 测试给出结果 OneTimeSetUp: 未找到合适的构造函数

    我有一个问题 NUnit 告诉我 没有找到合适的构造函数 这是什么原因造成的 我还收到另一条消息 异常没有堆栈跟踪 这两条消息只是一遍又一遍地重复 这是我的代码 TestFixture public class SecurityServic
  • 在c#中搜索支持rar格式的压缩库

    我想在我的应用程序中添加功能来解压缩 并可选择压缩 各种格式的文件 我有支持 zip gzip 7zip 和 bzip2 的库 但还是没有找到支持rar的库 我知道 rar 是商业的 但也许有一些 net 库可用于解压缩 rar s 最好是

随机推荐

  • 烦人的 vim(取消)缩进规则

    当编辑 PHP 代码 我不确定它是否特定于该语言 并且我在跨多行的逗号分隔列表中间创建一个新行时 缩进规则总是取消我要离开的行的缩进 这是一个视频 http toogeneric com files indent2 mov这种情况发生在数组
  • 等待审核的典型时间? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我将我的第
  • ValueError:无法将大小为 2 的序列复制到维度为 4 的数组轴

    谁能向我解释一下这个错误来自哪里 这意味着什么 我该如何解决这个问题 也许我的问题太笼统了 抱歉 但我不知道我应该在这里放更多什么 P Error Traceback most recent call last File C test 7
  • 大型对象的 Redux 性能

    我正在使用 Redux 和 React 构建一个 Web 应用程序 我的应用程序是一个呈现大量数据的分析应用程序 当我的商店变大时 我会遇到性能问题 避免 redux 中大数据出现性能问题的首选方法是什么 应用结构 我的应用程序的结构是这样
  • AWS 证书管理器 api 不显示导入的证书

    虽然证书管理器 UI 显示我导入的证书状态为 已颁发 但当尝试从 ELB 应用程序 lb 使用它时 我得到 没有可用的证书 对 api 的 POST 请求返回空列表 另外 当我运行 aws acm list certificates max
  • 维护 .NET 项目中引用的 COM dll 的正确版本

    我想在 NET 项目中引用 COM DLL 但我还想确保创建的互操作 DLL 具有正确的版本 以便补丁知道何时必须更改 DLL 如果我使用TlbImp我可以用以下命令指定所需的版本 asmversion标志 但当我直接从 Visual St
  • 如何在反应头盔中预加载最大内容的绘画图像

    我在灯塔收到这个警告 我尝试做 了解更多 链接告诉我要做的事情 并在图像的头部包含一个预加载标签 但我仍然收到警告 我尝试了这个预加载标签 该网址是当我右键单击图像并选择 在新选项卡中打开 时浏览器中的网址 图像刚刚导入到 jsx 组件中
  • Python csv writer 分隔符错误?

    免责声明 我在欧洲 根据这一页 http www paessler com knowledgebase en topic 2293 i have trouble opening csv files with microsoft excel
  • SimpleForm 不带 for(非模型表单)

    是否可以在没有模型的情况下使用简单表单 由 Plataformatec 提供 https github com plataformatec simple form https github com plataformatec simple
  • Xcode 静态分析器抱怨使用 ARC 时存在潜在泄漏

    我正在使用 ARC 和 ios sdk 6 0 我很确定我有一些内存泄漏 我很难追踪到 运行静态分析器后 我收到有关以下两种方法的警告 id
  • 在 Visual Studio 中调暗/隐藏代码日志行

    有什么方法可以使 Visual Studio 变暗或隐藏 显示我的代码的按需日志记录行 我们在项目中使用了大量的日志记录 并且很难阅读这样的代码 我希望它是这样的 例如 Unobtrusive Code 扩展对我来说适用于 Visual S
  • 是否可以通过编程方式禁用 iOS 7 中的控制中心?如果不能,有哪些替代方法?

    我开发了一个使用自下而上滑动手势的应用程序 它在 iOS 6 中工作得很好 但现在 iOS 7 出来了 它可能工作了二十五次之一 我几乎每次都会得到 iOS 7 控制中心 显然 可以在 设置 中禁用控制中心 但这取决于手机所有者 我无法控制
  • Python 中的“变量 //= 值”语法是什么意思? [复制]

    这个问题在这里已经有答案了 我遇到了代码语法d 2其中 d 是变量 这不是任何循环的一部分 我不太明白这个表达 有人可以启发我吗 是楼层划分操作员 这 旁边的意思是 就地 对变量进行操作 它类似于 and 运算符 如果您以前见过这些运算符
  • Python-算法语句

    我想编写一个执行以下操作的程序 输入示例 3 10 4 18 2 6 19 24 1 20 预期输出 4 2 2 2 6 1 1 输入将来自一个文件 其中第一行将包含窗口大小 N 第二行将包含由空格分隔的数字流 您需要输出每个窗口中以空格分
  • Jquery Datatable 将一行从一个表拖放到另一个表

    我正在使用 jquery dataTables js 并且尝试将行从一个表拖放到另一个表 反之亦然 从表 2 拖放到表 1 如下示例所示 http jsfiddle net yf47u http jsfiddle net yf47u 上面的
  • jenkins Slave 以用户身份运行

    我有一个詹金斯设置 有多个用户登录活动目录插件 http www greenreedtech com jenkins active directory 这很有用 这样每个用户都可以访问自己的任务 然而 每个用户在本地网络上也有不同的权限 例
  • 我可以传递前向声明的枚举值吗?

    当向前传递声明的结构或类时 必须通过引用或指针将其传递给函数 但是 前向声明的枚举可以做什么呢 它是否还必须通过引用或指针传递 或者说 可以传递一个值吗 下一个示例使用 g 4 6 1 编译良好 include
  • 从“Android 私人库”中删除灰显的项目。无法删除罐子

    我有一个 Eclipse 项目 我正在尝试将库更新为较新的 Jar 文件 但是 Eclipse 项目不允许我删除旧的库 我关闭了 eclipse 并尝试从文件夹中手动删除它并重新启动 eclipse 但它仍然不允许我现在编译 因为旧的 ja
  • 将 dd-mm-yyyy 字符串转换为日期

    我正在尝试使用以下命令将 dd mm yyyy 格式的字符串转换为 JavaScript 中的日期对象 var from datepicker val var to datepickertwo val var f new Date from
  • 如何使用 LanguageExt EitherAsync 返回 Left 的非错误类型?

    我有一个方法 可以在数据库中查找会员卡 如果找到并且有效则返回它 或者返回enum值 如果没有 这允许调用代码打开enum价值 我想退货Either