Open cmeeren opened 1 year ago
I am not in favour:
'a
can be rounded. The idea that this could be generic is unlikely to work.Math.Round
(or equivalents for other numerics types), with MidpointRounding
overloads is the most explicit.So I believe the existing Math.Round
etc API is good.
The only thing wrong with Math.Round
is the implementation, throwing for negative decimal places. While creating an F# round might be a chance to have a correct implementation, it's better to fix at the source, in dotnet/runtime, rather than creating fixed versions in F#, if possible.
This issue isn't fully specified as not all types
'a
can be rounded. The idea that this could be generic is unlikely to work.
It would work the same as the existing round
, which uses SRTP and requires a Round
member IIRC.
The value seems low as if any function is in non curried form the user can easily create a curried version, and vice versa. So creating duplicates of existing methods and exposing them purely in order to have non-curried or curried forms doesn't seem worth it.
It is not trivial to create a curried version in this case, since round
(and therefore a generic roundTo
) uses static member constraints. I haven't looked at the implementation of round
, but if you do, I am sure you will agree that it is not something that any F# user can trivially write. (I am happy to be proven wrong, of course.)
Rounding is a complex operation and likely to be used in places which can easily go wrong and using a specialized function
Math.Round
(or equivalents for other numerics types), withMidpointRounding
overloads is the most explicit.
Could you elaborate a bit more on this? I fail to see the big issue here, or how it is different to the existing round
. I have either a float
, a single
, a decimal
or similar that I want to round using normal rounding rules, just like round
, except that I want to specify the number of decimal places.
Just one additional idea on top of this. I am surprised that System.Math.Round can't round int
with a negative digits
argument. That is something that I actually need in many places in my source, and then also with several of the variations in the optional third argument - the MidpointRounding
.
let x: int = 12345678 // millimeters, integral type
Math.Round(x, -1) |> Console.WriteLine // 12345680
Math.Round(x, -2) |> Console.WriteLine // 12345700
Math.Round(x, -2, MidpointRounding.ToZero) |> Console.WriteLine // 12345600
In my source, which deals heavily with lengths of wood, I have standardized internally exclusively on millimeters. In many places in the source these lengths have to be truncated or rounded, in various ways, to centimeters, decimeters and meters. I do that while still keeping the internal representation in millimeters. So I have this whole bunch of functions that do all the calculations to truncate and round to these various precisions for int16, int32 and int64. It would've been so much easier if Math.Round could have taken care of all of this for me.
So, obviously, the point is: If we get a roundTo
, perhaps it can do this as well. I understand it might complicate the implementation for normal use, and also maybe throw coders off somehow (... I mean, a negative argument? ...), so that it's better to have another function, and perhaps even put it in a library such as FSharpPlus, if it isn't there already. But I would like it...
I propose we add
roundTo: int -> 'a -> 'a
that is similar to the existinground
but rounds to the specified number of decimal places.The existing way of approaching this problem in F# is to use
System.Math.Round
, which is not pipe-friendly. Defining a pipe-friendly helper for this that works with multiple number types is non-trivial.Pros and Cons
The advantages of making this adjustment to F# are: Improved utility out of the box.
The disadvantages of making this adjustment to F# are: None?
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.