我正在尝试编写一个计算表达式,有效地处理来自所有依赖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#中做同样的事情 - 这有可能吗?