Maybe monad 允许链接一组所有可能失败的操作符(通过返回 None),Some result
如果每个子操作成功,或者None
任何失败,最后返回。这是一个小的虚拟示例:
type MaybeBuilder() =
member this.Return(x) =
Some x
member this.Bind(m, f) =
match m with
| Some x -> f x
| None -> None
let maybe = MaybeBuilder()
let list = [1;2;3;4]
// evaluates to Some 3
maybe {
let! x1 = List.tryFind ((=) 1) list
let! x2 = List.tryFind ((=) 2) list
return x1 + x2
}
// evaluates to None
maybe {
let! x1 = List.tryFind ((=) 1) list
let! x2 = List.tryFind ((=) 6) list
return x1 + x2
}
这大致相当于:
// evaluates to Some 3
match List.tryFind ((=) 1) list with
| None -> None
| Some x1 ->
match List.tryFind ((=) 2) list with
| None -> None
| Some x2 -> Some (x1 + x2)
// evaluates to None
match List.tryFind ((=) 1) list with
| None -> None
| Some x1 ->
match List.tryFind ((=) 6) list with
| None -> None
| Some x2 -> Some (x1 + x2)
在我的一段代码中,我目前正在做与此相反的操作,返回第一个成功的命中:
// evaluates to Some 1
match List.tryFind ((=) 1) list with
| Some x1 -> Some x1
| None ->
match List.tryFind ((=) 2) list with
| Some x2 -> Some x2
| None -> None
// evaluates to Some 2
match List.tryFind ((=) 6) list with
| Some x1 -> Some x1
| None ->
match List.tryFind ((=) 2) list with
| Some x2 -> Some x2
| None -> None
这是否也可以通过 monad 来获得良好的计算表达式语法?