Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F#: Reduce this function

Tags:

lint

f#

Consider the following piece of code:

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

findCoefficient returns a decimal, and scores is a Map<string, decimal>

Now when I write this piece of code in Visual Studio, the F# Power Tools give me this 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

How would I do this in this case?

like image 754
Snake Avatar asked Nov 25 '15 12:11

Snake


1 Answers

This is a terrible advice from the linter, but it follows a valid reasoning.

I replace conversion.Coefficient in your original snippet to make it a bit shorter:

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

When you have a binary operator in F# such as a + b, this can be rewritten as a function application (+) a b - and so we can rewrite the above code as:

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

Now, this is just a nested function application and so we can rewrite it with |>:

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

And now you can do what the linter suggests, which is to turn it into a function composition:

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

This is not something I would ever want to write in practice, but you can see how the rules that the linter follows in other (reasonable) cases apply here. But I'd recommend opening an issue with the F# PowerTools suggesting that the linter should not give silly advice when the function involves binary operators :-).

like image 117
Tomas Petricek Avatar answered Nov 06 '22 00:11

Tomas Petricek