Search code examples
f#generic-constraints

Why can't we satisfy F# static member constraints with type extensions?


I'd like to be able to extend types from other libraries with static methods to enable generic arithmetic. Take, for example, the newly minted SIMD-friendly fixed-size VectorN types from Microsoft. They define Zero, they define (+), they define (/), but I can't use Array.average on them because they don't define DivideByInt, which I'd be happy to:

open System.Numerics
type Vector2f with 
  static member DivideByInt (v:Vector2f) (i:int) = v / Vector2f(single i, single i)
let bigArray : Vector2f[] = readABigFile()
printf "the average is %A" (Array.average bigArray)

But it won't let me compile, complaining

error FS0001: The type 'Vector2f' does not support the operator 'DivideByInt'

Why does this limitation exist in the F# compiler?

(Edit: essentially the same question was asked previously.)


Solution

  • It is not currently possible to define an operator overload in a type extension. There is an F# language user voice item for this (with quite a lot of votes) and so this is something that might change in future versions of F# (I think it would be great addition that fits nicely with the F# design).

    If you absolutely need something like this today, you can either create a lightweight wrapper for your type that adds the operators, or you can use a (somewhat scary) trick that lets you hide the standard operator with a new overloaded one. The following question has both examples: Global operator overloading in F#