You mix two types of syntax to define a fact function.
When using the function keyword, it implicitly adds an argument, which is then used in certain branches. If you check the signature of your fact definition, you will see float -> float -> float instead of float -> float . The first float in your definition matches n , the second is added by the fact that you are using the function keyword.
You can use either the keyword
let fact = function | 0.0 -> 1.0 | n -> [1.0 .. n] |> List.reduce (*)
or an explicit match expression (the compiler will be able to infer type n as a float , you do not need to specify it manually)
let fact n = match n with | 0.0 -> 1.0 | _ -> [1.0 .. n] |> List.reduce (*)
Note, although this will not be a practical problem in this case, comparing floats with exact values ββis usually not a good idea due to their binary representation. In your case, it may make sense to support fact work with integers, and then give the result:
let term n = (e ** n) / (float (fact (int n)))
source share