F#:有效的前缀运算符是什么?

Joe*_*ler 17 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.
Run Code Online (Sandbox Code Playgroud)

编辑:

Brian的链接包括以下有效前缀运算符列表:

! (or repetitions of !)
~ (or repetitions of ~)
+
-
+.
-.
%
%%
&
&&
Run Code Online (Sandbox Code Playgroud)

我的链接下面仅列出了这些运算符:

~
!
?
Run Code Online (Sandbox Code Playgroud)

快速测试表明,MSDN文档似乎不符合语言规范.谢谢,Brian.

Ola*_*laf 15

有两种类型的前缀运算符:tilde-prefixed运算符和bang-prefixed运算符.Tilde-prefixed运算符以波形符号"〜"开头,而bang-prefixed运算符以"!"开头.主要区别在于,在应用波形符前缀运算符时,省略了波形符.

Tilde前缀运算符

带波形符的前缀运算符以波形符"〜"开头,后跟其中一个:
+, - ,+., - .,%,%%,&,&&

一个波形前缀运算符也可以构建为任意数量的波浪号的列表:
~~,~~~,~~~~,~~~~~,...

当你应用操作符时,你必须省略波浪号,除非它是波浪蛇.

???????????????????????????????????????????????????????
? declaration ?   usage    ?         remark           ?
???????????????????????????????????????????????????????
? ~~          ? ~~         ?                          ?
? ~~~         ? ~~~        ?                          ?
? ~~~~~~~~~   ? ~~~~~~~~~  ? or any number of tildes  ?
? ~+          ? +          ?                          ?
? ~+.         ? +.         ?                          ?
? ~-          ? -          ?                          ?
? ~-.         ? -.         ?                          ?
? ~%          ? %          ?                          ?
? ~%%         ? %%         ?                          ?
? ~&          ? &          ?                          ?
? ~&&         ? &&         ?                          ?
???????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

Bang-prefixed运算符

一个爆炸前缀的操作员以爆炸"!"开头.其次是这些字符的任意组合:
!,%,&,*,+,.,/,<,=,>,@,^,|,〜,?

此规则的例外是"!=".前缀运算符不得以此组合开头.

此表列出了一些示例.

???????????????????????????????
? declaration  ?    usage     ?
???????????????????????????????
? !!           ? !!           ?
? !%           ? !%           ?
? !&           ? !&           ?
? !*           ? !*           ?
? !+           ? !+           ?
? !.           ? !.           ?
? !/           ? !/           ?
? !<           ? !<           ?
? !>           ? !>           ?
? !@           ? !@           ?
? !^           ? !^           ?
? !|           ? !|           ?
? !~           ? !~           ?
? !?           ? !?           ?
? !@=@>        ? !@=@>        ?
? !!!/<=>@!!!* ? !!!/<=>@!!!* ?
???????????????????????????????
Run Code Online (Sandbox Code Playgroud)

代码段代字号 - 前缀运算符

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
Run Code Online (Sandbox Code Playgroud)

代码段bang-prefixed运算符

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 ( !| ) (SomeString s) = "!| " + s 
let ( !~ ) (SomeString s) = "!~ " + s 
let ( !? ) (SomeString s) = "!? " + s 
let ( !@=@> ) (SomeString s) = "@=@> " + s 
let ( !!!/<=>@!!!* ) (SomeString s) = "!!!/<=>@!!!* " + s 
//let ( != )   (SomeString s) = "!= " + s   // prefix != is not allowed
//let ( !=@@ ) (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" (!@ 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
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很棒的总结!它还解释了文档中一些尚不清楚的问题。 (2认同)

Bri*_*ian 14

看到

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

但我认为它没有完整的规则.)

以下符号操作标记可用于形成表达式:

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 ~) 
    +
    -
    +.
    -.
    %
    %%
    &
    &&
Run Code Online (Sandbox Code Playgroud)

由以下组成的运算符始终是前缀运算符:

  • 重复 !
  • 重复〜

不允许以这些字符开头的其他运算符.

运算符+, - ,+., - .,%,&,&&和可以用作前缀和中缀运算符.当用作前缀运算符时,这些运算符具有~prepended的隐式运算符名称.例如,-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)
Run Code Online (Sandbox Code Playgroud)