Common Functions in F #

I'm still trying to wrap my head around how F # generalizes (or not) functions and types, and there is a case that listens to me:

let min(a, b) = if a < b then a else b let add(a, b) = a + b let minInt = min(3, 4) let minFloat = min(3.0, 4.0) // works! let addInt = add(3, 5) let addFloat = add(3.0, 5.0) // error: This expression was expected to have type // int but here has type float 

Here min has the general type 'a * 'a -> 'a (requires comparison) , and add has a specific type int * int -> int , apparently derived from its first use in the program. Both are declared and used the same way, so why the difference in generalization?

I understand that in case of adding, the problem can be postponed by declaring the inline function, which forces it to get a definition of a general type, i.e. 'a * 'b -> 'c (requires member (+)) , but this does not explain why this is necessary in this case, and not in another.

+6
source share
3 answers

There is a great @TomasP article in this release: http://tomasp.net/blog/fsharp-generic-numeric.aspx

When writing simple general code that has some parameter of type T, we don’t know anything about the type parameter, and there is no way to limit it to a numeric type, which provides all the operators that we may need to use in our code. This is a limitation of the .NET runtime. and F # provides two ways to overcome it.

But why is < and > (and by extension, = , <= and >= ) OK?

The F # compiler treats equality and comparison differently (see section 5.2.10 “Limitations of Equality and Comparison” in specifications, thanks to @Daniel). You get a special comparison restriction, which is allowed (just see the Specification for more details):

If the type is a named type, then the type definition does not have, and it is not assumed that the NoComparison attribute and the type definition implement System.IComparable or are an array type or System.IntPtr or System.UIntPtr.

There is no such special handling for the + operator. Why can't there be restrictions like numeric ?

Well, isn't this statement defined for strings? In some languages ​​for listings and collections? Of course, this will be an addable constraint, not a numeric . Then many such overloaded operators can be found in a program with different semantic meanings. Thus, F # provides a catch-all method with static member constraints and the inline keyword. Only equality and comparison are special.

+7
source

why is the difference in generalization?

There is a trade-off between general and performance. The comparison constraint provides generality for functions of type min , which can affect any value of any type F #, but in general it refers to virtual dispatching and is many times slower. The + operator provides limited generality and can act on any value of any type F #, which was supplemented by overload, but does not work in the general case and therefore is always very fast, because sending is never required.

+2
source

comparison is a compilation time limit. Therefore, the question remains: why add not generalized? As Yamen pointed out, general mathematical operations require nesting, which affects the size and performance of the code - perhaps this is not something the compiler should do automatically.

+1
source

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


All Articles