Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of addition (+) in F#

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.)

like image 758
Lasse Espeholt Avatar asked Jun 08 '11 21:06

Lasse Espeholt


People also ask

What are the types of addition?

The 4 main properties of addition are commutative, associative, distributive, and additive identity.

What are the addition names?

The numbers that are added are called addends, and the total value is called the sum. In the above example, 6 and 4 are addends, and 10 is the sum.


2 Answers

Briefly, F# has an ad-hoc-overloading mechanism via the inline keyword and "static member constraints". There is some further magic specific to the built-in math operators, which magically assumes type int the 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.

like image 130
Brian Avatar answered Sep 30 '22 14:09

Brian


Overloaded functions (and operators) must be marked inline in F#. This is because they depend on explicit member constraints. Those constraints are resolved at compile time. A function let inline add a b = a + b has the type 'a -> 'b -> 'c (requires member (+)) where + is a static function/operator. You can't do this in C#; it doesn't have static member constraints.

let inline add a b = a + b
add 1 2 //works
add 1.0 2.0 //also works
like image 28
Daniel Avatar answered Sep 30 '22 16:09

Daniel