1

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

4

0 回答 0