Статические методы расширения, поддерживающие ограничения элементов

Мне нужно реализовать статический метод расширения, поддерживающий ограничения членов для некоторых базовых примитивных типов, таких как целые числа, числа с плавающей запятой и т. Д. Вот мой код для целых чисел со знаком:

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

Код теста:

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

Но компилятор жалуется на ошибку:

Тип System.Int32 не поддерживает операторы с именем Foo.

Что мне здесь не хватает? Спасибо!


person Stringer    schedule 09.09.2010    source источник
comment
Если я правильно вас понимаю, я думаю, что даже если вы можете это сделать, это не особенно хорошая идея. Работа с базовыми языковыми механизмами всегда казалась мне антипаттерном. Подумайте о том, что кому-то, кроме вас, возможно, придется поработать над этим кодом в какой-то момент в будущем. Возможно, вам даже придется поддерживать этот код самостоятельно в какой-то момент в будущем, когда вы не работали над ним какое-то время. Модификации внутренних типов могут привести к нескольким WTF? моменты.   -  person Onorio Catenacci    schedule 10.09.2010


Ответы (2)


Ограничения статических членов в F # никогда не находят «методы расширения», они могут видеть только внутренние методы для типов (и несколько особых случаев, указанных в спецификации языка F #).

Возможно, вы можете вместо этого использовать перегрузку метода? Какова ваша конечная цель?

person Brian    schedule 09.09.2010
comment
Спасибо. Конечной целью было добавить мой собственный набор встроенных функций в FSharp.Core.Operators, таких как тригонометрические функции и т. Д. - person Stringer; 10.09.2010

Ограничения статического типа F # не работают с методами расширения. Методы расширения не могут быть проверены статически во время компиляции, и даже в этом случае вы можете иметь несколько определений для Int32 :: Foo (в зависимости от того, какое пространство имен вы импортировали).

К сожалению, для решения вашей проблемы вам, возможно, придется прибегнуть к использованию отражения.

person Chris Smith    schedule 09.09.2010
comment
Я не думаю, что это технически невыполнимо - методы расширения проверяются статически во время компиляции (когда вы их вызываете), поэтому они также могут быть приняты ограничениями членов. Имеет смысл, что это не поддерживается, но это должно быть возможно ... - person Tomas Petricek; 10.09.2010