I think Generic Arithmetic is a common problem in .NET languages. There are many articles explaining the different approaches, and very soon I will publish another one explaining mine, which is similar to the solution you posted.
Now, if you ask me whether to use it, I would say: as long as you understand what you are doing, why not? I use it partly in production and have no problems at all, but since I really like runtime performance, I use overloading to resolve everything at compile time. Then, to speed up the compilation time, I redefine the basic mathematical operators to work in the same type, otherwise the types of signatures become very complex and can take an age to compile.
There are more things to consider, but for your specific problem, here is a sample code:
open System.Numerics type FromInt = FromInt with static member ($) (FromInt, _:sbyte ) = fun (x:int) -> sbyte x static member ($) (FromInt, _:int16 ) = fun (x:int) -> int16 x static member ($) (FromInt, _:int32 ) = id static member ($) (FromInt, _:float ) = fun (x:int) -> float x static member ($) (FromInt, _:float32 ) = fun (x:int) -> float32 x static member ($) (FromInt, _:int64 ) = fun (x:int) -> int64 x static member ($) (FromInt, _:nativeint ) = fun (x:int) -> nativeint x static member ($) (FromInt, _:byte ) = fun (x:int) -> byte x static member ($) (FromInt, _:uint16 ) = fun (x:int) -> uint16 x static member ($) (FromInt, _:char ) = fun (x:int) -> char x static member ($) (FromInt, _:uint32 ) = fun (x:int) -> uint32 x static member ($) (FromInt, _:uint64 ) = fun (x:int) -> uint64 x static member ($) (FromInt, _:unativeint) = fun (x:int) -> unativeint x static member ($) (FromInt, _:bigint ) = fun (x:int) -> bigint x static member ($) (FromInt, _:decimal ) = fun (x:int) -> decimal x static member ($) (FromInt, _:Complex ) = fun (x:int) -> Complex(float x,0.0) let inline fromInt (a:int) : ^t = (FromInt $ Unchecked.defaultof< ^t>) a module NumericLiteralG = let inline FromZero() =LanguagePrimitives.GenericZero let inline FromOne() = LanguagePrimitives.GenericOne let inline FromInt32 (i:int) = fromInt i
source share