我正在尝试编写一个计算表达式,该表达式可以有效地处理来自所有相关 let 的警告和错误!参数并将它们与给定计算的结果结合起来。问题是从所有使用的 let 中获取错误列表!在定义的计算结果之后将它们连接起来。为了显示:
给定类型
type ValueWithErrors<'value> =
| Value of 'value * string list
| Undefined of string list
以及此阶段的粗略绑定函数:
let public bind calculation = function
| Value(value, errors) ->
try
let result = calculation(value)
match result with
| Value(resultValue, resultErrors) -> Value(resultValue, (errors |> List.append resultErrors))
| Undefined(resultErrors) -> Undefined(errors |> List.append resultErrors)
with
| _ as ex -> Undefined(ex.Message :: errors)
| Undefined(errors) -> Undefined(errors)
我想编写一个计算函数,允许我执行以下操作:
calc {
let! value1 = ValueWithErrors (5, ["ERROR"])
let! value2 = ValueWithErrors (6, ["ERROR2"])
return (value1 + value2)
}
结果为 Value(11, ["ERROR", "ERROR2"])
所以我这样定义了一个不完整的构建器(注意 Return() impl 缺失)
type public ValueWithErrorsBuilder() =
member this.Bind(m, f) =
bind f m
member this.ReturnFrom(value) =
value
member this.Return(value) =
Value(value, []) // This is wrong, don't have access to previous binding
在 C# 中,我可以使用自定义类型上的自定义 SelectMany(source, calc, resultSelector) 扩展方法轻松完成此操作,并且 LINQ 查询语法会出现错误。像这样:
from value1 in ValueWithErrors (5, ["ERROR"])
from value2 in ValueWithErrors (6, ["ERROR2"])
select (value1 + value2)
我想在 F# 中做同样的事情 - 这可能吗?