Этот вопрос немного двусмысленный, поэтому я просто расскажу о том, что верно для F #.
В F # методы могут быть перегружены, как C #.Методы всегда доступны по квалифицированному имени в форме someObj.MethodName
или someType.MethodName
.Должен быть контекст, который может статически разрешать перегрузку во время компиляции, как в C #.Примеры:
type T() =
member this.M(x:int) = ()
member this.M(x:string) = ()
let t = new T()
// these are all ok, just like C#
t.M(3)
t.M("foo")
let f : int -> unit = t.M
let g : string-> unit = t.M
// this fails, just like C#
let h = t.M // A unique overload for method 'M' could not be determined
// based on type information prior to this program point.
В F # значения функций с привязкой не могут быть перегружены.Итак:
let foo(x:int) = ()
let foo(x:string) = () // Duplicate definition of value 'foo'
Это означает, что у вас никогда не будет «неквалифицированного» идентификатора foo
, который имеет перегруженное значение.Каждое такое имя имеет единственный недвусмысленный тип.
Наконец, сумасшедший случай, который, вероятно, и вызывает вопрос.F # может определять inline
функции, которые имеют «статические ограничения членов», которые могут быть связаны, например, со «всеми типами T
, которые имеют свойство члена с именем Bar
» или что-то еще.Этот вид обобщенности не может быть закодирован в CIL.Вот почему функции, использующие эту функцию, должны быть inline
, чтобы на каждом сайте вызовов код, специфичный для типа используемого на месте вызова, генерировался встроенным.
let inline crazy(x) = x.Qux(3) // elided: type syntax to constrain x to
// require a Qux member that can take an int
// suppose unrelated types U and V have such a Qux method
let u = new U()
crazy(u) // is expanded here into "u.Qux(3)" and then compiled
let v = new V()
crazy(v) // is expanded here into "v.Qux(3)" and then compiled
Таким образом, все это обрабатывается компилятором, и к тому времени, когда нам нужно сгенерировать код, мы снова статически решили, какой конкретный тип мы используем на этом месте вызова.«Тип» crazy
не является типом, который может быть выражен в CIL, система типов F # просто проверяет каждый вызов, чтобы убедиться, что соблюдаются необходимые условия, и вставляет код в этот сайт, очень похоже на работу шаблонов C ++.
(Основное назначение / обоснование сумасшедших вещей - перегруженные математические операторы. Без функции inline
оператор +
, например, являющийся типом функции с привязкой по буквам, может либо «только»работать на int
s "или" работать только на float
s "или еще много чего. Некоторые разновидности ML (F # является родственником OCaml) делают именно это, где, например, оператор +
работает только на int
s,и отдельный оператор, обычно называемый +.
, работает на float
s, тогда как в F # +
- это функция inline
, определенная в библиотеке F #, которая работает с любым типом с оператором +
или любым другимиз простых числовых типов. Встраивание может также иметь некоторые потенциальные преимущества производительности во время выполнения, что также привлекательно для некоторых математических / вычислительных областей.)