Existing answers already explain that saving a wrapper function is a good idea, as it allows you to make the code as modular as possible. This would not be very obvious with a simple example, but in real projects it would be a big advantage to expand sizeFmt at some point by setting more parameters - consider that sometimes you may need "Hertz" instead of "Bytes" (and division by 1000 instead of 1024), or a sting pattern template (five decimal digits), or a localized list of multipliers, etc.
Regarding the second question translating to float , the solution is very simple: make value a statically resolved type :
let inline humanReadable (value:^T) = sizeFmt (float value) 0
This will cause humanReadable to have the following type constraint:
val inline humanReadable : value: ^T -> unit when ^T : (static member op_Explicit : ^T -> float)
Using:
humanReadable 42424242.42 // float humanReadable 4242 // int humanReadable 42424242424242424242I // Numerics.BigInteger humanReadable (424242424242424242422424N / 5N) // BigRational
Using float in an internal function seems to be in order: any rounding errors will be eliminated by a series of divisions.
source share