I just learned that OCAML have to have a . postfix for doing float arithmetic. An example would be 3. +. 4. which equals 7. (float). However, F# handles float and integer arithmetic in the same way, so both 3 + 4 (int) and 3. + 4. (float) works.
F# have + naturally assigned to int so let add a b = a + b is of type int -> int -> int. And indeed (+) gives me val it : (int -> int -> int) = <fun:it@6-1>.
That leads to the following sequence which I think quite counter-intuitive:
> 3. + 4.;;
val it : float = 7.0
> (+);;
val it : (int -> int -> int) = <fun:it@8-2>
So my question is: Is the “overloading” done by a special mechanism/case in the compiler or is this a language-wide thing so I potentially can define a function called add (or anything else) which have a one definition for integers and one for floats (or any other type.)
Briefly, F# has an ad-hoc-overloading mechanism via the
inlinekeyword and “static member constraints”. There is some further magic specific to the built-in math operators, which magically assumes typeintthe absence of other constraints.(+)is just about the most special/magical thing in all of F#, so it does not make for a nice introduction to the language/type system.In general, “overloading” is difficult for statically-typed, type-inferred languages. F#’s choices here are very pragmatic. OCaml does a different, simple, pragmatic thing (no overloading). Haskell does a different, complex-but-elegant thing (type classes). They’re all somewhat reasonable points in the language/library design space.