F#:减少这个函数

F#: Reduce this function

考虑以下代码:

scores |> Map.fold (fun state key value ->
                    state + (findCoefficient conversion.Coefficients key) * value) 
                   0m

findCoefficient returns一个小数,而scores是一个Map<string, decimal>

现在,当我在 Visual Studio 中编写这段代码时,F# Power Tools 会给我这个 lint suggestion/warning:

Lint: If no mutable arguments are partially applied in the chain of function calls, then the function calls and lambda could be replace with composition. e.g. fun -> x |> isValid |> not could be replaced with isValid >> not

在这种情况下我该怎么做?

这是来自 linter 的 糟糕 建议,但它遵循有效的推理。

我将您原来的代码段中的 conversion.Coefficient 替换为更短的代码:

scores |> Map.fold (fun state key value ->
  state + (findCoefficient coeff key) * value) 0m

当您在 F# 中有一个二元运算符时,例如 a + b,这可以重写为函数应用程序 (+) a b - 因此我们可以将上面的代码重写为:

scores |> Map.fold (fun state key value ->
  (+) state ((*) (findCoefficient coeff key) value)) 0m

现在,这只是一个嵌套函数应用程序,所以我们可以用 |>:

重写它
scores |> Map.fold (fun state key value ->
  value |> (*) (findCoefficient coeff key) |> (+) state) 0m

现在你可以按照 linter 的建议去做,即将它变成一个函数组合:

scores |> Map.fold (fun state key ->
  (*) (findCoefficient coeff key) >> (+) state) 0m

这不是我 曾经 想要在实践中写的东西,但您可以看到 linter 在其他(合理的)情况下遵循的规则如何适用于此。但我建议用 F# PowerTools 打开一个问题,建议当函数涉及二元运算符时,linter 不应该给出愚蠢的建议:-)。