Подтвердить что ты не робот

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, похоже, не соответствуют спецификации языка. Спасибо, Брайан.

4b9b3361

Ответ 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 ~) 
    +
    -
    +.
    -.
    %
    %%
    &
    &&

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

  • повторный!
  • repeat ~

Другие операторы, начинающиеся с этих символов, не разрешены.

Операторы +, -, +., -.,%, &, && & и могут использоваться как как префиксные, так и инфиксные операторы. При использовании в качестве префиксных операторов эти операторы имеют неявное имя оператора с ~ добавлением. Например, -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

Ничего, я думаю, что нашел список здесь, во второй таблице под заголовком "Перегруженные имена операторов".