Search code examples
f#generic-programming

Is there generic MultiplyByInt?


There's a generic function LanguagePrimitives.DivideByInt to divide by int without losing generic behavior, we can use it like this:

let inline Divideby2 n = LanguagePrimitives.DivideByInt n 2

val inline Divideby2 :
    ^a ->  ^a when  ^a : (static member DivideByInt :  ^a * int ->  ^a)

But there's no function called MultiplyByInt to perform generic multiplication by int. Is there anything to perform generic multiplication? Like this:

let inline MultiplyBy2 n = SomeGenericFunctionsModule.MultiplybyInt n 2;

P.S. we can always use some non-standard approach like:

let inline MultiplyByInt n m = seq { for i in 1..m -> n} |> Seq.sum

but I'm interested if it is possible to do in the right way.


Solution

  • I'm afraid there's no built-in function, but I can propose two alternative solutions:

    type MulExtension = MulExtension of int with
        static member (=>) (x:float  , MulExtension y) = x * (float y)
        static member (=>) (x:decimal, MulExtension y) = x * (decimal y)
        static member (=>) (x:int64  , MulExtension y) = x * (int64 y)
        // More overloads
    
    let inline MultiplyByInt x y = x => MulExtension y
    

    But you'll have to specify each type. I would rather use this function:

    let inline MultiplyByInt  x y = 
        let fromInt (n:int) : ^a when  ^a : (static member (*) : ^a * ^a -> ^a) =
            System.Convert.ChangeType(n, typeof<'a>) :?> 'a
        x * (fromInt y)
    

    I can't see any difference in performance between both methods.