Summations and products and factorials oh my The proper title of this question should be "Summations and products, and factorials oh my!".



After getting quite a bit of useful feedback on this question from @mjolka, and a comment, I decided that there were many things to be improved.

These are the following things that I've added/changed:


A factorial function which uses the product function.
Support for getting the sum, and product of sequences with no elements.
Strongly typed anonymous function parameters.


Again, for those who don't know, a summation is defined as follows:


  $$\sum_{n=a}^{b}f(n)$$


And a product is defined as follows:


  $$\prod_{n=a}^{b}f(n)$$


I'd like to know the following things, which are more or less mostly the same as the ones in the last question:


Am I writing this in a proper functional way?
How can I reduce the repetitiveness in my code?
Is there a way to improve performance? It already runs pretty fast, at approximately \$0.025\$ seconds for inputs of \$10\$).
Anything else?


Here's the code:

let inline summation (f: (double -&gt; double)) low high =
    match (low, high) with
    | (low, high) when low &lt;&gt; high -&gt;
        { low .. high } 
        |&gt; Seq.map f
        |&gt; Seq.sum
    | (low, high) when low = high -&gt; 0.0
    | _ -&gt; -1.0

let inline product (f: (double -&gt; double)) low high =
    match (low, high) with
    | (low, high) when low &lt;&gt; high -&gt;
        { low .. high }
        |&gt; Seq.map f
        |&gt; Seq.fold Checked.op_Multiply 1.0
    | (low, high) when low = high -&gt; 1.0
    | _ -&gt; -1.0

let inline factorial n =
    product (fun x -&gt; x) 1.0 n


Here's a few small tests to ensure that the code works:


[&lt;EntryPoint&gt;]
let main argv =
    System.Console.WriteLine(summation (fun x -&gt; x) 1.0 10.0)
    System.Console.WriteLine(product (fun x -&gt; x) 1.0 10.0)
    System.Console.WriteLine(factorial 10.0)
    0



And here's expected output of the above tests:


55
3628800
3628800
Some comments:

    |&gt; Seq.map f
    |&gt; Seq.sum


is just

Seq.sumBy f


Otherwise, if perf really matters I would avoid using Seq, and probably combine the map and fold in the product case.

Also, rather than

match (low, high) with
| (low, high) when low &lt;&gt; high -&gt;
    { low .. high } 
    |&gt; Seq.map f
    |&gt; Seq.sum
| (low, high) when low = high -&gt; 0.0


I would use an if to avoid the warning about incomplete pattern match so it would become

if low=high then 0.0
else   {low .. high} |&gt; Seq.sumBy f