我有一个看起来有点像这样的C#方法:
bool Eval() {
// do some work
if (conditionA) {
// do some work
if (conditionB) {
// do some work
if (conditionC) {
// do some work
return true;
}
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
在F#中,由于强制性的其他分支,这最终看起来有点丑陋:
let eval() =
// do some work
if conditionA then
// do some work
if conditionB then
// do some work
if conditionC then
// do some work
true
else
false
else
false
else
false
Run Code Online (Sandbox Code Playgroud)
用F#写这个更干净的方法是什么?
Dan*_*iel 13
module Condition =
type ConditionBuilder() =
member x.Bind(v, f) = if v then f() else false
member x.Return(v) = v
let condition = ConditionBuilder()
open Condition
let eval() =
condition {
// do some work
do! conditionA
// do some work
do! conditionB
// do some work
do! conditionC
return true
}
Run Code Online (Sandbox Code Playgroud)
如评论中所述,您可以反转条件.这简化了C#代码,因为您可以编写:
if (!conditionA) return false;
// do some work
Run Code Online (Sandbox Code Playgroud)
虽然F#没有命令性返回(如果你想返回,你需要真假分支),它实际上也简化了这段代码,因为你可以写:
let eval() =
// do some work
if not conditionA then false else
// do some work
if not conditionB then false else
// do some work
if not conditionC then false else
// do some work
true
Run Code Online (Sandbox Code Playgroud)
您仍然需要false多次写入,但至少您不必将代码缩进太多.有无限数量的复杂解决方案,但这可能是最简单的选择.至于更复杂的解决方案,您可以使用允许使用命令式返回的F#计算表达式.这类似于Daniel的计算,但更强大一些.
好吧,既然'做一些工作'已经势在必行(大概),那么我认为
let eval() =
let mutable result = false
... // ifs
result <- true
... // no more elses
result
Run Code Online (Sandbox Code Playgroud)
更短更合理.(换句话说,else只对if返回值的表达式是强制性的;因为你正在做必要的工作,所以使用if不需要的语句else.)
请不要害怕提取功能.这是控制复杂逻辑的关键.
let rec partA () =
// do some work
let aValue = makeA ()
if conditionA
then partB aValue
else false
and partB aValue =
// do some work
let bValue = makeB aValue
if conditionB
then partC bValue
else false
and partC bValue =
// do some work
conditionC
Run Code Online (Sandbox Code Playgroud)