Ошибка: неожиданный инфиксный оператор в выражении, об успешно скомпилированном префиксном операторе

Немного поиграв с инфиксными операторами, я был удивлен следующим:

let (>~~~) = function null -> String.Empty | s -> s  // compiles fine, see screenshot
match >~~~ input with .... // error: Unexpected infix operator in expression

val (>~~~): строка -> строка ~~~): строка -> строка">

а также:

Неожиданный инфиксный оператор

Изменение первых символов префиксного оператора (на !~~~ например) исправляет это. То, что я получаю сообщение об ошибке, что инфиксный оператор является неожиданным, довольно странно. Зависание показывает определение быть string -> string,

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

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

Неверное определение оператора

1 ответ

Решение

Правила для пользовательских операторов в F# довольно жесткие - поэтому, даже если вы можете определить пользовательские операторы, существует множество правил их поведения, и вы не можете их изменить. Особенно:

  • Только некоторые операторы (в основном те, с ! а также ~) может использоваться в качестве префиксных операторов. С ~ Вы также можете перегружать унарные операторы +, -, ~ а также ~~, так что если вы определите оператор с именем ~+., вы можете использовать его как, например, +. 42,
  • Другие операторы (в том числе те, которые начинаются с >) можно использовать только как инфикс. Вы можете превратить любой оператор в обычную функцию, используя круглые скобки, поэтому (+) 1 2 является действительным.
  • ? Символы являются специальными (они используются для динамического вызова) и не могут появляться в качестве первого символа пользовательского оператора.

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

Другие вопросы по тегам