F # и op_GreaterThan - PullRequest
       12

F # и op_GreaterThan

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

Я недавно пытался написать что-то на F #, используя Microsoft Solver Foundation Services, и при этом натолкнулся на проблему: мне пришлось выразить условие (Term> Term), которое в C # можно было бы просто выразить как t1 > t2 и возвращает другой объект Term. Вместо этого в F # мне пришлось вызывать Term.op_GreaterThan, чтобы достичь того же результата, что при использовании t1> t2 получилось бы логическое значение, а не термин.
Теперь мне интересно, почему F # выбирает только op_GreaterThan, если он дает логическое значение? И какой смысл будет иметь интерпретация F # для t1> t2, пока Term не реализует IComparable?
Пожалуйста, помните, что я понимаю, почему, делая такое с равенством и полным равенством на основе понятия структурного сравнения, я просто не понимаю, как это можно расширить до сравнений «больше, чем» / «меньше, чем».

Ответы [ 3 ]

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

Учебник Ответ:

Перегрузка операторов не является частью Спецификации общего языка, то есть разработчики компиляторов могут игнорировать ее или поддерживать только частично, если они этого хотят. Как автор библиотеки вы несете ответственность за предоставление людям альтернативных способов работы с классом.

Прагматичный ответ:

Потому что это глупо, в первую очередь. Метод op_GreaterThan был явно создан для сравнения. Что это, вы не должны делать «интересные» вещи с этим, как объединение двух терминов. CLR позволяет вам злоупотреблять этим только потому, что он должен поддерживать устаревшие языки, такие как C ++.

Кстати, существует перегрузка специально для объединения двух вещей. Это называется op_Concatenate. Вы действительно должны рассмотреть возможность его использования вместо op_GreaterThan.

EDIT

Почти Хороший Ответ:

В F # оператор конкатенации, о котором я упоминал, был ^.

Я называю это почти хорошим ответом, потому что я не уверен, что C # поддерживает это. Я думаю, что это разрешено только в VB и F #.

РЕДАКТИРОВАТЬ # 2

Кажется, что F # не соблюдает перегрузку ^ в конце концов.

РЕДАКТИРОВАТЬ # 3

WTF здесь происходит? F # вообще не поддерживает оператор>. Конечно, вы можете перегрузить его, и он будет правильно генерировать метод op_GreaterThan, но игнорирует его. Он даже не пытается использовать op_GreaterThan, вместо этого он ищет интерфейс System.IComparable.

Еще хуже, это проверка во время выполнения. Несмотря на то, что он может статически определить, что класс Foo не реализует IComparable, он все равно работает и компилирует код в любом случае.

2 голосов
/ 08 июня 2009

Интуитивно понятно, что оператор сравнения, такой как >, всегда должен давать логическое значение!

Вы можете ответить на вопрос a > b с да или нет, но не с 3 или new Stopwatch().

Когда он может вернуть что-то еще, что-то вроде

if a < b then

больше не имеет смысла.

F # -объекты (кортежи, списки и т. Д.) Часто реализуют IComparable или IStructuralComparable, что позволяет, например, лексикографически сортировать кортеж.

* Примечание:

ИМХО, это не лучшее решение, позволяющее сравнивать любые объекты и затем генерировать исключения во время выполнения. Haskell решил эту проблему лучше, используя классы типов.

greater :: (Ord a) => a -> a -> Bool
greater a b = a < b

Сравнение несопоставимых типов завершится ошибкой во время компиляции.

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

Вам не нужно использовать операторы <и>. В классе Solver Foundation Services Model есть методы Greater и Less, вы должны иметь возможность использовать их вместо этого.

...