3
votes

In F# why does my add function not add two floats

let add a b = a+b

(add 3 4) //returns 7
(add 3.5 5.5) //error

also please explain how type inference works in F#.

Thanks.

4
You may be confusing type inference and templates in C++ or generics in C#. - Roman
Thanks to remind. Will not forget this in future. - hrishikeshp19

4 Answers

7
votes

You have to make it inline.

let inline add a b = a+b

The problem is that + is an inline operator, so if your function add is not inline it will take the default overload which is for int.

Have a look at this answer Use of `inline` in F#

When the function is declared inline, type inference will infer the static type constraints.

val inline add :
   ^a ->  ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)

So now a and b could be any type that implement the static member (+) with that signature.

2
votes

If you only want your function to work with floats use a type annotation.

let add (a:float) b = a + b //float -> float -> float
0
votes

In F#, the type inference system just puts a type of int when you are dealing with numbers, due to technical restrictions. In Haskell, add :: Num a => a -> a -> a works because of typeclasses, which is different from .NET classes. Typeclasses do not fit F#.

See http://en.wikibooks.org/wiki/F_Sharp_Programming/Basic_Concepts#Type_Inference and http://en.wikibooks.org/wiki/F_Sharp_Programming/Values_and_Functions

0
votes

My two cents here.

Actually if you change the order of the execution to,

let add a b = a+b

(add 3.5 5.5) //returns 9.0
(add 3 4) //error

You will see that F# does do add to two floats. ( This answers your question In F# why does my add function not add two floats )

And notice that in this snippet, F# infers the function add type as float -> float -> float.

Why F# infers function type differently in the two cases even you define the function in the exact same way?

I think that when you define the function, F# gives the type int to the function. But internally, F# remains flexible about the "true" type of the function. The first time/line you call the function, the compiler sees how you use it and thus your "intention" of the function type is understood by the compiler. And the compiler adjust the type accordingly.

Once the compiler "thinks" it gets the "true type" of the function, it is what it is. And due to that F# is statically typed, you cannot make a second call to the function with a different type of argument.

That being said, I recommend you try these snippet.

let add a b = a + b

add "str" "ing"

It should work.

let add a b = a + b

add 5. 6.
add "str" "ing" // error, check the type

Correct me if I am wrong. Hope this helps.