Type 'float & # 8594; float does not match type float

Just started learning F #, and I'm trying to generate and evaluate the first 10 members of the Taylor series for e. I originally wrote this code to calculate it:

let fact n = function | 0 -> 1 | _ -> [1 .. n] |> List.reduce (*) let taylor e = let term n = (e ** n) / (fact n) [1 .. 10] |> List.map (term) |> List.reduce (+) 

This results in an error because the ** operator does not work for int . Obviously, I need to throw everything on a float so that everything works correctly. So:

 let fact (n: float) = function | 0.0 -> 1.0 | _ -> [1.0 .. n] |> List.reduce (*) let taylor (e: float) = let term (n: float) = (e ** n) / (fact n) [1.0 .. 10.0] |> List.map (term) |> List.reduce (+) 

Which gives a compiler error:

 EvaluatingEtotheX.fs(9,39): error FS0001: The type 'float -> float' does not match the type 'float' EvaluatingEtotheX.fs(9,36): error FS0043: The type 'float -> float' does not match the type 'float' 

(line 9 contains let term n = (e ** n) / (fact n) ).

Why is this not working? What does this error mean anyway? Why does the compiler care to pass a function that gives a float , rather than the actual value of the float ? Note that I was just starting to learn F #, so I am not familiar with why this would not work in this case.

+5
source share
1 answer

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))) // assumes fact : int -> int 
+8
source

Source: https://habr.com/ru/post/1264327/