F #: Каковы действительные префиксные операторы?
Есть ли список допустимых имен операторов префикса? Я не смог найти его, но я заметил, что некоторые операторы, которые раньше были действительными в качестве префиксных операторов в последнем CTP, больше не действуют в RC.
let (~--) (str:string) = [str];;
-----^^^
stdin(4,6): error FS1208: Invalid operator definition.
Prefix operator definitions must use a valid prefix operator name.
Edit:
Ссылка Брайана включает следующий список действительных операторов префикса:
! (or repetitions of !)
~ (or repetitions of ~)
+
-
+.
-.
%
%%
&
&&
В моей ссылке ниже перечислены только эти операторы:
~
!
?
Быстрый тест показывает, что документы MSDN, похоже, не соответствуют спецификации языка. Спасибо, Брайан.
Ответы
Ответ 1
См
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc245030784
в котором излагаются правила. Я привел некоторые из них ниже. (См. Также
http://msdn.microsoft.com/en-us/library/dd233228(VS.100).aspx
но я думаю, что у него нет полных правил.)
Для формирования выражений можно использовать следующие символические-op-токены:
infix-op :=
or || & && <OP >OP $OP = |OP &OP ^OP :: -OP +OP *OP /OP %OP
**OP
infix-or=prefix-op :=
-OP +OP % %% & &&
prefix-op :=
! (or repetitions of !)
~ (or repetitions of ~)
+
-
+.
-.
%
%%
&
&&
Операторы, состоящие из следующих, всегда являются префиксными операторами:
Другие операторы, начинающиеся с этих символов, не разрешены.
Операторы +, -, +., -.,%, &, && & и могут использоваться как как префиксные, так и инфиксные операторы. При использовании в качестве префиксных операторов эти операторы имеют неявное имя оператора с ~ добавлением. Например, -x анализируется как приложение оператора ~ - к выражению x. Это имя также используется при определении определений для этих операторов префикса:
Это означает, что эти префиксные операторы определяются с добавленным символом ~:
// For a complete redefinition of the operator:
let (~+) x = x
// For defining the operator on a type:
type C(n:int) =
let n = n % 7
member x.N = n
static member (~+) (x:C) = x
static member (~-) (x:C) = C(-n)
static member (+) (x1:C,x2:C) = C(x1.N+x2.N)
static member (-) (x1:C,x2:C) = C(x1.N-x2.N)
Ответ 2
Существует два типа префиксных операторов: тильда-префиксы и операторы с префиксом. Операторы с тимме-префиксом начинаются с тильды "~", а операторы с префиксом начинаются с взрыва "!". Главное отличие заключается в том, что вы опускаете символ тильды, когда вы применяете оператор с тильдой-префиксом.
Операторы с префиксом тильды
Оператор с тильдой-префиксом начинается с тильды "~", за которой следует одна из следующих:
+, -, +., -.,%, %%, &, && </p>
Оператор с префиксом тильды также может быть создан как список любых чисел тильд:
~~, ~~~, ~~~~, ~~~~~,...
Когда вы применяете оператор, вам нужно опустить тильду, если она не является тильдской змеей.
╔═════════════╦════════════╦══════════════════════════╗
║ declaration ║ usage ║ remark ║
╠═════════════╬════════════╬══════════════════════════╣
║ ~~ ║ ~~ ║ ║
║ ~~~ ║ ~~~ ║ ║
║ ~~~~~~~~~ ║ ~~~~~~~~~ ║ or any number of tildes ║
║ ~+ ║ + ║ ║
║ ~+. ║ +. ║ ║
║ ~- ║ - ║ ║
║ ~-. ║ -. ║ ║
║ ~% ║ % ║ ║
║ ~%% ║ %% ║ ║
║ ~& ║ & ║ ║
║ ~&& ║ && ║ ║
╚═════════════╩════════════╩══════════════════════════╝
Операторы с префиксом с бай-ином
Оператор с префиксом, начинающийся с префикса, начинается с взрыва "!" за которым следует любая комбинация этих символов:
!,%, &, *, +,.,/, <, =, > , @, ^, |, ~,?
Исключением этого правила является "! =". Оператор префикса не должен начинаться с этой комбинации.
В этой таблице приведены некоторые примеры.
╔══════════════╦══════════════╗
║ declaration ║ usage ║
╠══════════════╬══════════════╣
║ !! ║ !! ║
║ !% ║ !% ║
║ !& ║ !& ║
║ !* ║ !* ║
║ !+ ║ !+ ║
║ !. ║ !. ║
║ !/ ║ !/ ║
║ !< ║ !< ║
║ !> ║ !> ║
║ [email protected] ║ [email protected] ║
║ !^ ║ !^ ║
║ !| ║ !| ║
║ !~ ║ !~ ║
║ !? ║ !? ║
║ [email protected][email protected]> ║ [email protected][email protected]> ║
║ !!!/<=>@!!!* ║ !!!/<=>@!!!* ║
╚══════════════╩══════════════╝
Фрагменты кода с типлом-префиксом
type SomeString = SomeString of string
let ( ~~ ) (SomeString s) = "~~ " + s
let ( ~~~ ) (SomeString s) = "~~~ " + s
let ( ~~~~~~~~~ ) (SomeString s) = "~~~~~~~~~ " + s
let ( ~+ ) (SomeString s) = "~+ " + s
let ( ~+. ) (SomeString s) = "~+. " + s
let ( ~- ) (SomeString s) = "~- " + s
let ( ~-. ) (SomeString s) = "~-. " + s
let ( ~% ) (SomeString s) = "~% " + s
let ( ~%% ) (SomeString s) = "~%% " + s
let ( ~& ) (SomeString s) = "~& " + s
let ( ~&& ) (SomeString s) = "~&& " + s
let x = SomeString "tilde"
printf "%s\n" (~~ x) // ~~ tilde
printf "%s\n" (~~~ x) // ~~~ tilde
printf "%s\n" (~~~~~~~~~ x) // ~~~~~~~~~ tilde
printf "%s\n" (+ x) // ~+ tilde
printf "%s\n" (+. x) // ~+. tilde
printf "%s\n" (- x) // ~- tilde
printf "%s\n" (-. x) // ~-. tilde
printf "%s\n" (% x) // ~% tilde
printf "%s\n" (%% x) // ~%% tilde
printf "%s\n" (& x) // ~& tilde
printf "%s\n" (&& x) // ~&& tilde
Операторы с флип-префиксом кода
type SomeString = SomeString of string
let ( !! ) (SomeString s) = "!! " + s
let ( !% ) (SomeString s) = "!% " + s
let ( !& ) (SomeString s) = "!& " + s
let ( !* ) (SomeString s) = "!* " + s
let ( !+ ) (SomeString s) = "!+ " + s
let ( !. ) (SomeString s) = "!. " + s
let ( !/ ) (SomeString s) = "!/ " + s
let ( !< ) (SomeString s) = "!< " + s
let ( !> ) (SomeString s) = "!> " + s
let ( [email protected] ) (SomeString s) = "[email protected] " + s
let ( !^ ) (SomeString s) = "!^ " + s
let ( !| ) (SomeString s) = "!| " + s
let ( !~ ) (SomeString s) = "!~ " + s
let ( !? ) (SomeString s) = "!? " + s
let ( [email protected][email protected]> ) (SomeString s) = "@[email protected]> " + s
let ( !!!/<=>@!!!* ) (SomeString s) = "!!!/<=>@!!!* " + s
//let ( != ) (SomeString s) = "!= " + s // prefix != is not allowed
//let ( [email protected]@ ) (SomeString s) = "!= " + s // prefix != is not allowed
let y = SomeString "bang"
printf "%s\n" (!! y) // !! bang
printf "%s\n" (!% y) // !% bang
printf "%s\n" (!& y) // !& bang
printf "%s\n" (!* y) // !* bang
printf "%s\n" (!+ y) // !+ bang
printf "%s\n" (!. y) // !. bang
printf "%s\n" (!/ y) // !/ bang
printf "%s\n" (!< y) // !< bang
printf "%s\n" (!> y) // !> bang
printf "%s\n" ([email protected] y) // [email protected] bang
printf "%s\n" (!^ y) // !^ bang
printf "%s\n" (!| y) // !| bang
printf "%s\n" (!~ y) // !~ bang
printf "%s\n" (!? y) // !? bang
printf "%s\n" ([email protected][email protected]> y) // [email protected][email protected]> bang
printf "%s\n" (!!!/<=>@!!!* y) // !!!/<=>@!!!* bang
Ответ 3
Ничего, я думаю, что нашел список здесь, во второй таблице под заголовком "Перегруженные имена операторов".