如何声明全局级别可重载的运算符?

时间:2013-02-18 06:03:50

标签: syntax f# operators

基于:Is possible to define same-named operator for different argument count?

我想定义一些像+这样的运算符,但让-|-调用

let a = -|- 1
let b = 1 -|- 1
let c = 1 -|- 1 1 1 1

至少有2个第一行适用于+但是如何声明自己的运算符呢?

2 个答案:

答案 0 :(得分:5)

我认为通常没有一种直接的方法可以做到这一点。您可以使用具有静态成员约束的inline运算符来覆盖您想要的某些案例,但我认为它不会非常优雅。

对于某些运营商名称,您可以定义单独的前缀 infix 版本,其中包含前两种情况:

// Prefix version of the operator (when you write e.g. '+. 10')
let (~+.) a = a * 10
// Infix version of the operator (when you write e.g. '1 +. 10')
let (+.) a b = a + b

// Sample use
+. 10
10 +. 20

您仍然无法编写10 +. 20 30 40,因为那时您需要一个重载的中缀运算符。

值得注意的是,您不能对所有运营商名称执行此操作。以下是中缀运算符的允许运算符名称F# specification的语法定义:

  

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

     

前缀-op:=
  缀或前缀运算
  ~~~~~~(和任何重复的〜)
  !OP(除了!=)

PS:我通常不是自定义操作员的忠实粉丝 - 在某些情况下,它们很好,但很难发现(你没有在IntelliSense中看到它们),除非你使用标准操作符在数值计算中,通常很难理解它们的含义。所以我可能会考虑其他方法......

答案 1 :(得分:1)

那么被歧视的联盟呢?

type RHS = 
|One of int
|Two of int * int
...

然后

let (-|-) a b =
    match b with
    |One(a) -> ...
    |Two(a,b) -> ...
     ...

用以下方式调用:

1 -|- One(1)
1 -|- Two(1,1)
....