Hi this is a bit of a hidden gem but what you are looking for is this:
let inline (/!) (a : ^a) (b : ^a) : ^a =
if b = LanguagePrimitives.GenericZero
then LanguagePrimitives.GenericZero
else a / b
btw: this has this monster type:
val inline ( /! ) :
a: ^a -> b: ^a -> ^a
when ^a : equality and ^a : (static member get_Zero : -> ^a) and
^a : (static member ( / ) : ^a * ^a -> ^a)
(this is why I don't really like to write this in the declaration ;) )
As you can see there is support for generic numeric code, but it's not that often discussed (F# has some type-class like things build in - this is a example, the others are stuff like comparable
, etc.)
Tomas wrote a good article about this: Writing generic numeric code
PS you don't need the ^a
either - but I kindof like to write the signature - and even if you can do this:
let inline (/!) a b =
if b = LanguagePrimitives.GenericZero
then LanguagePrimitives.GenericZero
else a / b
val inline ( /! ) :
a: ^a -> b: ^b -> ^c
when ( ^a or ^b) : (static member ( / ) : ^a * ^b -> ^c) and
^b : (static member get_Zero : -> ^b) and ^b : equality and
^c : (static member get_Zero : -> ^c)
it will do you no good as the real division operators are usually only on one type for both arguments - and as I said: I like to emphazise the types over the argument-names ;)
fun fact
you can get around the GenericZero
thing like this:
> let inline (/!) a b = if b = (b-b) then (b-b) else a/b;;
val inline ( /! ) :
a: ^a -> b: ^b -> ^b
when ( ^a or ^b) : (static member ( / ) : ^a * ^b -> ^b) and
^b : (static member ( - ) : ^b * ^b -> ^b) and ^b : equality
(Just to be safe: you might run into trouble with certain types / numbers here ;) )