views:

103

answers:

2

I need to implement a static extension method supporting member constraints on some basic primitive types like integers, floats, etc. Here's my code for signed integers:

module MyOperators =
    let inline foo (x : ^T) = (^T : (static member Foo : ^T -> int) (x)) 

    type System.Int32 with 
        static member Foo(x : Int32) = 7 // static extension

Test code:

open MyOperators    
let x = foo 5 // x should be 7

But compiler complains with error:

The type 'System.Int32' does not support any operators named 'Foo'

What am I missing here? Thanks!

+4  A: 

Static member constraints in F# never find 'extension methods', they can only see intrinsic methods on types (and a few special cases called out in the F# language spec).

Perhaps you can use method overloading instead? What is your ultimate goal?

Brian
Thanks. Ultimate goal was to add my own set of intrinsics to FSharp.Core.Operators, such as trigonometrical functions, etc.
Stringer Bell
+3  A: 

F#'s static type constraints don't work with extension methods. Extension methods cannot statically be checked at compile time, and even so, you can have multiple definitions for Int32::Foo (depending on which namespace you imported).

Unfortunately, to solve your problem you might have to resort to using reflection.

Chris Smith
Ok I see, that sounds a good reason. Thanks!
Stringer Bell
@Chris: I don't think this is technically infeasible - extension methods are checked statically at compile time (when you call them), so they could be also accepted by member constraints. It makes sense that this is not supported, but it should be possible...
Tomas Petricek
Good call, my bad.
Chris Smith