代码之家  ›  专栏  ›  技术社区  ›  Arshia001

如何根据f中许多昂贵的计算结果来计算结果#

  •  0
  • Arshia001  · 技术社区  · 6 年前

    假设我有以下伪C代码:

    TResult MyMethod()
    {
        var firstTry = SomeExpensiveComputation1();
        if (firstTry.IsSuccessful) return firstTry;
    
        var secondTry = SomeExpensiveComputation2();
        if (secondTry.IsPartiallySuccessful)
        {
            var subTry1 = SomeExpensiveComputationOn2_1(secondTry);
            if (subTry1.IsSuccessful) return subTry1;
    
            var subTry1 = SomeExpensiveComputationOn2_2(secondTry);
            if (subTry1.IsSuccessful) return subTry1;
        }
    
        return LastExpensiveComputationThatNeverFails();
    }
    

    如果我是在f_做这个的话,它会是这样的:

    let MyMethod () =
        let firstTry = SomeExpensiveComputation1 ()
        if firstTry.IsSuccessful then firstTry else
            let secondTry = SomeExpensiveComputation2 ()
            if secondTry.IsSuccessful then
                let subTry1 = SomeExpensiveComputationOn2_1 ()
                if subTry1.IsSuccessful then subTry1 else
                    let subTry2 = SomeExpensiveComputationOn2_2 ()
                    if subTry2.IsSuccessful then subTry2 else LastExpensiveComputationThatNeverFails ()
            else
                LastExpensiveComputationThatNeverFails()
    

    正如你在上面看到的,我不得不重复 LastExpensiveComputationThatNeverFails 两次。这不必是一个方法调用,它可以是许多行内联计算(例如,尝试从缓存中获取一些值,如果它不存在,计算它)。可以将代码重构成另一个函数,但我仍然不喜欢相同的代码,即使它只是一行,必须写两次(或更多),因为这会导致重复和混乱的维护。用f_编写这种代码的正确方法是什么?

    0 回复  |  直到 6 年前
        1
  •  3
  •   Just another metaprogrammer    6 年前

    我想可以 LastExpensiveComputationThatNeverFails 在需要结果时调用的本地函数。

    但是,也可以将操作更改为返回 Option<_> 使用内置的组合函数。

    let MyMethod () =
      SomeExpensiveComputation1 ()
      |> Option.orElseWith
        ( fun () -> 
            SomeExpensiveComputation2 ()
            |> Option.bind (fun _ -> SomeExpensiveComputationOn2_1 () |> Option.orElseWith SomeExpensiveComputationOn2_2)
        )
      |> Option.orElseWith LastExpensiveComputationThatNeverFails
    

    Option.orElseWith LastExpensiveComputationThatNeverFails 仅当上一个结果为 None 如果失败的话。