为什么 $ 被允许但 $$ 或 <$> 被禁止作为运算符 (FS0035) 是什么让 $ 如此特别?

Why is $ allowed but $$, or <$> disallowed as an operator (FS0035) and what makes $ special?

$ 允许在自定义运算符中使用,但如果您尝试使用 $$<$> 或例如 ~$% 作为运算符名称,您将收到以下信息错误:

error FS0035: This construct is deprecated: '$' is not permitted as a character in operator names and is reserved for future use

$ 显然 名称中也有“$”,但有效,为什么? 即:

let inline ( $ ) f y = f y

// using it works just fine:
let test = 
    let add x = x + 1
    add $ 12

我在在线示例中经常看到 $ 并且显然是一种特殊的运算符。 $ 的这种特殊待遇或作用是什么(即在 Haskell 或 OCaml 中),如果允许 <$> 应该做什么(编辑)?

试图通过创建像 op_DollarDollar 这样的函数来欺骗系统,但不会成功,语法检查也在调用站点上完成。尽管作为示例,此技巧确实适用于其他(合法)运算符:

// works
let inline op_BarQmark f y = f y
let test = 
    let add x = x + 1
    add |? 12

// also works:
let inline op_Dollar f y = f y
let test = 
    let add x = seq { yield x + 1 }
    add $ 12

F# specification 围绕这一点存在一些不一致。 F# 规范的第 3.7 节将符号运算符定义为

regexp first-op-char = !%&*+-./<=>@^|~ 
regexp op-char       = first-op-char | ? 

token quote-op-left  =
    |  <@ <@@  

token quote-op-right  =
    |  @> @@>  

token symbolic-op  =
    | ?
    | ?<-
    | first-op-char op-char*
    | quote-op-left
    | quote-op-right

(并且 $ 也没有作为符号关键字出现在 3.6 节中),这表明编译器接受 ( $ ) 作为运算符是错误的。

但是,第 4.4 节(涵盖运算符优先级)包含以下定义:

infix-or-prefix-op :=
    +,  -, +., -., %, &, && 

prefix-op :=
    infix-or-prefix-op
    ~ ~~ ~~~             (and any repetitions of ~)
    !OP                  (except !=) 

infix-op :=
    infix-or-prefix-op  
    -OP +OP || <OP >OP = |OP &OP ^OP *OP /OP %OP !=  
                         (or any of these preceded by one or more ‘.’) 
    := 
    :: 
    $ 
    or 
    ?

以及随后的优先级和结合性 table 确实包含 $(但没有迹象表明 $ 可以作为一个字符出现在任何更长的符号运算符中)。考虑提交错误,以便规范可以通过某种方式保持一致。