Summations and products in F# I was bored, and looking to do something that involved anonymous functions, and it was suggested by @Quill, that I create a summation function. I decided to also include a product function as well to top the whole thing off.

For those who don't know, a summation is usually defined like this:


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


And a product is usually defined like this:


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


I'd like to know the following things:


Am I doing this in a proper functional way?
Is there a way to reduce the repetitiveness of the code?
Is it okay to use List.fold to multiply all the elements of a list together? Is there a better way?
Am I violation any style guidelines?
Anything else?


Here's the code:

/// &lt;summary&gt;
/// Find the summation in a specific range, given
/// a specific function.
/// &lt;/summary&gt;
let summation func low high =
    let function_result_set: int list = [for x in low..high do yield x |&gt; func]
    let result = function_result_set |&gt; List.sum
    result

/// &lt;summary&gt;
/// Find the product in a specific range, given
/// a specific function.
/// &lt;/summary&gt;
let product func low high =
    let function_result_set: int list = [for x in low..high do yield x |&gt; func]
    let result = function_result_set |&gt; List.fold (*) 1
    result


And finally, here's a few tests:


[&lt;EntryPoint&gt;]
let main argv =
    System.Console.WriteLine(summation (fun n -&gt; n) 1 10)
    System.Console.WriteLine(product (fun n -&gt; n) 1 10)
    System.Console.ReadKey() |&gt; ignore
    0



And here's the desired output from the above tests:


55
3628800
Starting with summation,


let summation func low high =
    let function_result_set: int list = [for x in low..high do yield x |&gt; func]
    let result = function_result_set |&gt; List.sum
    result



First of all, we can remove result

let summation func low high =
    let function_result_set: int list = [for x in low..high do yield x |&gt; func]
    function_result_set |&gt; List.sum


Next, we don't need to construct a list containing func(low) .. func(high); we can instead operate over a sequence, meaning we don't have to have all those values in memory at once.

let summation func low high =
    let function_result_set = Seq.map func { low .. high }
    function_result_set |&gt; Seq.sum


Now we can make it a bit more succinct

let summation func low high =
    Seq.map func { low .. high } |&gt; Seq.sum


Finally, we can make it more generic by using statically resolved type parameters. At the moment, if we have a call to summation like this:

printfn "%d" &lt;| summation id 1 10


then summation will be constrained to be of type (int -&gt; int) -&gt; int -&gt; int -&gt; int. We can fix this by making the function inline:

let inline summation func low high =
    Seq.map func { low .. high } |&gt; Seq.sum


Now  summation has type ('a -&gt; 'b) -&gt; 'a -&gt; 'a -&gt; 'b and the following code will compile:

printfn "%d" &lt;| summation id 1 10
printfn "%f" &lt;| summation id 1.0 10.0


Similar comments hold for product, but with two additional things:


To make it generic we need to get the One property of the type ^a, and
I've used the checked version of * to check for overflow




let inline product func low high : ^a =
    Seq.map func { low .. high } |&gt; Seq.fold Checked.(*) LanguagePrimitives.GenericOne&lt; ^a &gt;