【问题标题】:LangageExt: Chaining of two Eithers with Bind(), but cannot figure out how to use them to create another EitherLangageExt:使用 Bind() 链接两个 Either,但无法弄清楚如何使用它们创建另一个 Either
【发布时间】:2020-11-04 13:02:18
【问题描述】:

我正在使用 LanguageExt 在 C# 中提供函数式编程功能。我有一个方法,我想在其中构建一个 VaultSharp 实例来访问我们的 HashiCorp Vault 服务。我的目标是通过两个 Either 的链创建一个 VaultClientSettings 实例(参见下面的方法)。最后,要么从链中的任何 Either 或实例中返回异常 Vault 客户端设置。我认为我很接近但无法完成最后一步。非常感谢您的建议。

这里是 C# 的 FP 库和 VaultSharp 库的链接;

这是显示我看到的错误的图像:

            Either<Exception, Uri> GetVaultUri() =>
                EnvironmentVariable.GetEnvironmentVariable(KVaultAddressEnvironmentVariableName)
                    .Map(uri => new Uri(uri));

            Either<Exception, TokenAuthMethodInfo> GetAuthInfo() =>
                EnvironmentVariable.GetEnvironmentVariable(KVaultTokenEnvironmentVariableName)
                    .Map(token => new TokenAuthMethodInfo(token));

            Either<Exception, VaultClientSettings> GetVaultClientSettings(
                Either<Exception, Uri> vaultUri,
                Either<Exception, TokenAuthMethodInfo> authInfo
            )
            {
                /////////////////////////////////////////////////////////////////////////
                // I have access to the uri as u and the authmethod as a, but I cannot //
                // figure out how to create the instance of VaultClientSettings.       //
                Either<Exception, VaultClientSettings>  settings =
                    vaultUri.Bind<Uri>(u =>
                        authInfo.Bind<TokenAuthMethodInfo>(a =>
                        {
                            Either<Exception, VaultClientSettings> vaultClientSettings = 
                                              new VaultClientSettings(u.AbsoluteUri, a);

                            return vaultClientSettings;
                        }));
            }

【问题讨论】:

    标签: c# functional-programming f# hashicorp-vault language-ext


    【解决方案1】:

    正如@hayden 已经指出的那样:绑定类型参数是错误的(无论哪种类型都需要是“正确”的结果类型)。

    对于 LanguageExt:如果返回正确的类型,甚至可以省略 type 参数:

    Either<Exception, VaultClientSettings>  settings =
                        vaultUri.Bind(u =>
                            authInfo.Bind(a =>
                            {
                                Either<Exception, VaultClientSettings> vaultClientSettings = 
                                                  new VaultClientSettings(u.AbsoluteUri, a);
    
                                return vaultClientSettings;
                            }));
    

    此代码的另一种形式 (LINQ) 可能对您来说更具可读性:

    var settings = from u in vaultUri
                   from a in authInfo
                   select new VaultClientSettings(u.AbsoluteUri, a);
    

    基本上BindSelectMany(来自...)

    【讨论】:

      【解决方案2】:

      没有使用过这两个库,但正在查看Bind 的签名:

      Either&lt;L, B&gt; Bind&lt;B&gt;(Func&lt;R, Either&lt;L, B&gt;&gt; f)

      从签名来看,以下内容应该是有效的:

      Either<Exception, VaultClientSettings>  settings =
          vaultUri.Bind<VaultClientSettings>(u =>
              authInfo.Bind<VaultClientSettings>(a =>
              {
                  Either<Exception, VaultClientSettings> vaultClientSettings = new VaultClientSettings(u.AbsoluteUri, a);
      
                  return vaultClientSettings;
              }));
      

      【讨论】:

      • 了解您如何推理使代码工作的方式非常有帮助!非常感谢您的帮助!
      猜你喜欢
      • 2021-03-24
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 2014-08-14
      相关资源
      最近更新 更多