F#: '&' оператор не должен обычно переопределяться

При определении пользовательского оператора от ограниченного набора односимвольных операторов, которые могут быть и инфиксными и префиксными операторами (+ - % &) Я решил использовать амперсанд, так как это - единственный из тех операторов, которые у меня до сих пор не было случая для использования в моем коде F#. Я обосновал, что с тех пор и, кажется, справедливо ограничил использование в F#, переопределение его наименее сбивало бы с толку людей, пользующихся моей библиотекой.

Однако, когда я делаю так, я получаю предупреждение компилятора:

'&' оператор не должен обычно переопределяться. Рассмотрите использование другого имени оператора.

Мой вопрос, почему этот по-видимому редкий оператор генерирует это предупреждающее сообщение, в то время как наиболее часто используемые операторы как плюс и минус не делают? Кроме того, как серьезно я должен взять это предупреждение?

6
задан Joel Mueller 22 February 2010 в 20:30
поделиться

2 ответа

Невозможно вызвать методы, использующие параметры byref. Это может быть или не быть большой проблемой для вас.

Что касается вашего вопроса о «шаблонах И», вот краткий пример. Однако следует отметить, что определение собственного унарного оператора и не повлияет на это поведение одного пути или другой.

let (|Contains|_|) (s:string) (x:string) =
  if (x.Contains(s)) then Some() else None

match "test" with
| Contains "e" & Contains "s" -> printfn "Success!"
| _ -> ()

Как ни странно, я вижу только предупреждение, которое вы упоминаете при определении бинарного оператора (&) , а не унарного оператора (~ &) .

EDIT

Хотя я не вижу, что он явно вызван в спецификации, похоже, что двоичный оператор & используется в качестве синонима двоичного оператора & & . Я бы предположил, что предложение не переопределять этот оператор существует, потому что это оператор короткого замыкания, но ваша перегрузка не может быть.

-121--4244482-

Среда выполнения Perl regex работает гораздо быстрее при работе с «фиксированными» или «привязанными» подстроками, а не с «плавающими» подстроками. Подстрока фиксируется, когда ее можно заблокировать в определенном месте исходной последовательности. И '^', и '$' обеспечивают эту привязку. Однако при использовании чередования «|» компилятор не распознает варианты как фиксированные, поэтому использует менее оптимизированный код для сканирования всей последовательности. И в конце процесса поиск фиксированных последовательностей дважды намного быстрее, чем поиск плавающей последовательности один раз. В связи с этим, чтение perl's regcomp.c заставит вас ослепнуть.

Обновить : Вот некоторые дополнительные детали. Вы можете запустить perl с флагом '-Dr', если вы скомпилировали его с поддержкой отладки и он будет выгружать данные компиляции regex. Вот что вы получаете:

~# debugperl -Dr -e 's/^\s+//g'
Compiling REx `^\s+'
size 4 Got 36 bytes for offset annotations.
first at 2
synthetic stclass "ANYOF[\11\12\14\15 {unicode_all}]".
   1: BOL(2)
   2: PLUS(4)
   3:   SPACE(0)
   4: END(0)
stclass "ANYOF[\11\12\14\15 {unicode_all}]" anchored(BOL) minlen 1

# debugperl -Dr -e 's/^\s+|\s+$//g'
Compiling REx `^\s+|\s+$'
size 9 Got 76 bytes for offset annotations.

   1: BRANCH(5)
   2:   BOL(3)
   3:   PLUS(9)
   4:     SPACE(0)
   5: BRANCH(9)
   6:   PLUS(8)
   7:     SPACE(0)
   8:   EOL(9)
   9: END(0)
minlen 1 

Обратите внимание на слово «заякоренный» в первой свалке.

-121--2678279-

При создании пользовательского оператора я, как правило, предпочитаю находить простую комбинацию символов, которая не конфликтует ни с одним существующим оператором F #. Верно то, что набор символов очень ограничен, поэтому это не всегда возможно. Однако можно, например, определить что-то вроде - & - , и часто можно выбрать какую-либо комбинацию, которая отражает значение оператора. Из любопытства, каким будет смысл вашего оператора?

В любом случае, когда я не могу найти хорошее имя оператора, то я считаю это признаком того, что, может быть, я не должен использовать пользовательский оператор (в конце концов, многие языки живут без них довольно легко). Я думаю, что основное использование пользовательских операторов, вероятно, некоторые специализированные математические вещи. Оператор (например, a - & - b ) часто можно заменить функцией, используемой при конвейерной обработке (например, a | > (В) ). Существует также аккуратный трюк , позволяющий использовать функции в качестве операторов инфикса.

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

EDIT Определение собственного оператора и не приведет к прерыванию другого использования символа и (при согласовании шаблонов). Вот пример и образец :

// define custom & operator
let (&) a b = a + b

match 2 with
| num1 & num2 -> num1 + num2 // Still works fine

и образцы позволяют сопоставить одно значение с несколькими узоров в одном образце (в примере выше мы просто связываем его с двумя различными значениями)

8
ответ дан 9 December 2019 в 20:42
поделиться

Вы не сможете вызывать методы, которые принимают параметры byref. Это может быть, а может и не иметь для вас большого значения.

Что касается вашего вопроса о «шаблонах И», вот небольшой пример. Однако обратите внимание, что определение собственного унарного оператора и не повлияет на это поведение тем или иным образом.

let (|Contains|_|) (s:string) (x:string) =
  if (x.Contains(s)) then Some() else None

match "test" with
| Contains "e" & Contains "s" -> printfn "Success!"
| _ -> ()

Как ни странно, я вижу только предупреждение, которое вы упоминаете при определении бинарного оператора (&) , а не унарного оператора (~ &) .

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

Хотя я не вижу, чтобы он явно вызывался в спецификации, похоже, что двоичный оператор & используется как синоним двоичного оператора && . Я предполагаю, что предложение не переопределять этот оператор существует, потому что это оператор короткого замыкания, но ваша перегрузка не может быть.

4
ответ дан 9 December 2019 в 20:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: