C#使用LanguageExt.Core:从Aff提取string并匹配Eff返回类型
问题分析
你的核心问题是Eff与Aff类型嵌套导致的类型不匹配:
runtime.Validate是Aff<Validation<Error, string>>类型- 你当前的代码没有将Aff的执行结果提取出来,而是把整个Aff实例作为Eff的返回值,最终得到
Eff<TRuntime, Aff<string>>,与方法声明的Eff<TRuntime, string>不符
解决方案
要解决这个问题,需要将Aff的操作嵌入到Eff的Monad链中,通过ToEff()方法将Aff类型转换为兼容的Eff类型,再逐步提取最终的string结果。
修正后的代码
using LanguageExt; using LanguageExt.Common; using static LanguageExt.Prelude; namespace ApplinxChannel.Api; public static class ValidationClass { public static Eff<TRuntime, string> Validate<TRuntime>() where TRuntime : struct, HasValidator<string> { return from runtime in Eff<TRuntime, TRuntime>(identity) // 将Aff转换为Eff,嵌入当前Monad链 from validationResult in runtime.Validate.ToEff() // 将Validation转换为Eff,处理错误聚合 from cleanedValue in validationResult.ToEff(errors => errors.Aggregate(Error.New("Errors: "), (e1, e2) => e1.Append(e2))) select cleanedValue; } }
代码解释
- 获取Runtime实例:第一个
from语句获取当前的TRuntime实例 - 转换Aff为Eff:通过
ToEff()将Aff<Validation<Error, string>>转换为Eff<TRuntime, Validation<Error, string>>,这样就能在Eff的Monad链中提取验证结果 - 处理Validation结果:
Validation.ToEff()会自动将成功的验证结果包装为SuccessEff<string>,失败时则将所有错误聚合成单个Error并包装为FailEff<string> - 返回最终字符串:最后提取验证通过的string值,完全匹配方法声明的返回类型
链式调用风格的替代写法
如果你偏好链式调用而非LINQ语法,也可以写成:
public static Eff<TRuntime, string> Validate<TRuntime>() where TRuntime : struct, HasValidator<string> { return Eff<TRuntime, TRuntime>(identity) .Bind(runtime => runtime.Validate.ToEff()) .Bind(validation => validation.ToEff(errors => errors.Aggregate(Error.New("Errors: "), (e1, e2) => e1.Append(e2)))); }
你之前尝试的错误原因
你尝试from validationAff in runtime.Validate(request)时报错,是因为Eff的Monad链无法直接绑定Aff类型,必须先通过ToEff()将Aff转换为与当前Eff上下文兼容的类型,才能在LINQ表达式中使用from提取值。
内容的提问来源于stack exchange,提问作者Marriv7.7
相关产品推荐
相关产品推荐

