F # и перегрузки оператора: (>) и (^) - PullRequest
3 голосов
/ 09 июня 2009

Хорошо, может кто-нибудь объяснить мне, почему F # позволяет вам перегружать операторы> и ^, но не позволяет вам их использовать?

+ (op_Addition): Works just fine.
^ (op_Concatenate): Compiler error in F#. Apparently only strings can be concatenated.
> (op_GreaterThan): Runtime Error – Failure during generic comparison: the type Program+OppTest4 does not implement the System.IComparable interface.

Если я скомпилирую свой код F # в виде библиотеки и использую эти операторы из VB, все они будут работать. Если я использую эти операторы из C #, все, кроме op_Concatenate работают (как и ожидалось). Но F # не только игнорирует некоторые из них, статическая проверка типов даже не говорит вам, что планирует это сделать.

Редактировать Пример кода

type OppTest4(value: int) =
   member this.value = value
   static member (^) (left : OppTest4, right : OppTest4) =
     OppTest4( Int32.Parse( left.value.ToString() ^ right.value.ToString()  ))
   static member (+) (left : OppTest4, right : OppTest4) =
     OppTest4(left.value + right.value )
   static member (>) (left : OppTest4, right : OppTest4) =
     left.value > right.value
   static member (<) (left : OppTest4, right : OppTest4) =
     left.value < right.value

Ответы [ 2 ]

4 голосов
/ 09 июня 2009

F # имеет значения по умолчанию для этих символов оператора, что разумно для F #. Вы всегда можете определить свои собственные значения, которые скрывают значения по умолчанию, например

let (>) x y = ...

Например, вы можете определить этот оператор как «T.operator> (U)» (при условии, что x имеет тип T, а y имеет тип U).

См. Prim-types.fs в FSharp.Core в исходном дистрибутиве для определения по умолчанию. (Они нетривиальны!)

Учитывая комбинацию (1) отсутствия поддержки механизма, подобного классу типов, в CLR (для определения общей семантики среди набора типов, не связанных между собой) и (2) того факта, что примитивные типы (например, int ') часто требуется специальный корпус для любой реализации языка программирования (например, System.Int32 не определяет метод operator +, но большинство языков программирования предпочитают вести себя так, как если бы такой метод существовал), трудно представить какой-либо вообще совместимый операторный материал на всех языках .Net сегодня. Есть много компромиссов в дизайне, в зависимости от того, что именно язык выбирает (слишком много взаимодействующих вопросов, чтобы здесь подвести итог). В любом случае вы должны иметь возможность вызывать любой метод из F #, и если поведение операторов по умолчанию нежелательно, вы можете переопределить (скрыть) операторы в соответствии с желаемым поведением. Если у вас есть какой-то конкретный сценарий, когда у вас возникают проблемы с выполнением работы, дайте мне знать.

EDIT

Я добавил больше деталей на

http://cs.hubfs.net/forums/thread/10869.aspx

0 голосов
/ 09 июня 2009

Согласен, есть несоответствие: оператор может быть определен, но не может быть использован.

Вы спрашиваете, почему дизайнеры F # решили реализовать сравнение с интерфейсом System.IComparable, а не перегружать операторов? Я не знаю почему, но в ОО-языке я бы предпочел IComparable, а не перегрузку операторов. Поэтому я бы предложил разработчикам F # нарушить совместимость с C # и запретить синтаксис «static member (>) (...)».

Если вы спрашиваете, как вызывать эти перегруженные операторы, это довольно просто: используйте статические члены op_Concatenate, op_GreaterThan или op_LessThan. (Действительно, у меня есть предупреждение компилятора, описывающее проблему. F # 1.9.6.16)

Runtime Ошибка приведения к System.IComparable без предупреждения компилятора, безусловно, является ошибкой. Вы можете отправить его по адресу fsbugs@microsoft.com.

...