Refactoring F# Imperative Code Towards Declarative
Recently, perusing the internet, I found an article which implements the trapezoidal rule in F#.
open System
let main() =
//Function to integrate
let f x =
10.0*x*x
let trapezoidal a b N =
let mutable xi = a
let h = (b - a)/N
let mutable suma = h/2.0*(f(a)+f(b))
for x in 1 .. System.Convert.ToInt32(N) do
let mutable xi1 = xi + h
suma <- suma + h*f(xi1)
xi <- xi1
suma
//some usage example
let fromA = 0.0
let toB = System.Math.PI
let counter = 100.0
let result = trapezoidal fromA toB counter
Console.Write("Result = ")
Console.Write(result)
main()
Although there is nothing inherently wrong with this piece of code, its imperative fashion doesn’t provide any benefit of functional approaches, such as expressiveness, minimizing mutability, reducing state side effects etc.
So, let’s try to come up with trapezoidal2 which will take advantage of declarative programming.
First, let’s extract initial values.
let h = (b - a)/N
let initialAccValue = h/2.0*(f(a)+f(b))
Array.fold
,
[|1 .. System.Convert.ToInt32(N)|]
|> Array.fold (fun acc i -> acc + //calculate increment here) initialAccValue
point(n) = point(n-1) + h
Luckily enough as h is constant we can also calculate it given first point and h
point(n) = point(0) + h*n
Or if we substitute our variables,
float(i)*h+a
suma + h*f(xi1)
acc + h*f(float(i)*h+a)
So, the entire function will look as follows
let trapezoidal2 a b N =
let h = (b - a)/N
let initialAccValue = h/2.0*(f(a)+f(b))
[|1 .. System.Convert.ToInt32(N)|]
|> Array.fold (fun acc i -> acc + h*f(float(i)*h+a)) initialAccValue