传播monad计算表达式时出错

时间:2014-11-03 05:34:59

标签: f# f#-3.0 computation-expression

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

0 个答案:

没有答案