F # overly aggressive type of output?

Therefore, while fulfilling some of the problems of Project Euler , I want to be able to use the square root of integer values ​​(int, long, bigint, etc.), but Sqrt is only defined for floating point values. So I wrote my own Newton-Raphson algorithm, and it is accurate enough for what I need. However, I want to be able to call the built-in sqrt function for floating point values. So I wrote something like this:

let inline dsqrt x = match box x with | :? float -> sqrt x | :? float32 -> sqrt x | _ -> p_dsqrt x 

My function is obviously called "p_dsqrt". However, this function requires that the Sqrt method be defined at the input, which spoils the entire target. Am I missing some type restriction, or what?

+4
source share
2 answers

I think you probably want this instead:

 let dsqrt x = match box x with | :? float as f -> sqrt f |> box :?> 'a | :? float32 as f -> sqrt f |> box :?> 'a | _ -> p_dsqrt x 

The problem with your code is that you are calling sqrt x directly, which limits the possible types of x . In my modified code, I bind the new identifier to the result of successfully enforcing float or float32 , so this does not float32 any restrictions on the type of x .

+3
source

If you want to use a match, the inline keyword is not required, but if you want to use the built-in function and "hat types", use overloading instead of matching:

 type Sqrt = Sqrt with // Dummy overload in order to get the right types inferred (will never reach here) static member inline ($) (Sqrt, _:^t when ^t:null and ^t: struct) = id // Existing sqrt static member inline ($) (Sqrt, x:'a) :'a = sqrt x // Your Newton-Raphson based sqrt's static member ($) (Sqrt, x:int ) = sqrtForInt x static member ($) (Sqrt, x:bigint) = sqrtForBigInt x let inline sqrt (x:'t) :'t = Sqrt $ x 

The return type will always be the same as the input type, and the implementation of the selected sqrt will depend on that type. This selection will be performed at compile time, which is the main difference between the matching method, which is allowed at run time.

If I endure a dummy overload, it will have the same problem as your code: this will require an sqrt constraint.

+6
source

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


All Articles