F#自定义操作符

简介: F#语言支持自定义操作符,特别是对于数学相关领域的应用来说,自定义类型上的操作符可以大大简化代码,提高程序可读性。本文就通过示例讲解全局自定义操作符和附属于特定类型的操作符。

    我们知道,不少编程语言都支持自定义操作符,特别是对于数学相关领域的应用来说,自定义类型上的操作符可以大大简化代码,提高程序可读性。对于F#来说,支持全局的自定义操作符和附属于特定类型的操作符。这里需要注意的就是,全局自定义操作符需要慎用,他可能会覆盖默认的操作符。

   下面我们定义一个全局操作符,具体示例如下:

//全局操作符,覆盖默认的letinline (+)(a : float)(b : float) =2.*a*b ;;

   在F#交互环境下(;;为结束标志),此示例执行如下:

1(16).jpg

   此时,输入 2. + 3. 的计算结果为12.0 。其中的2.是2.0的简写,代表float类型。另外,如果此时输入2 + 3 则提示错误,因为此为int类型,而定义的操作符参数类型是float,不兼容。

   还有一类就是对于自定义类型上的自定义操作符。这种比较常见,下面给出一个自定义复数类型,并给出自定义操作符的示例。

moduleYdMath//https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/operator-overloadingtypeComplex=        {
Real : floatImaginary : float        }
staticmember (+) (f1 : Complex, f2 : Complex) =letcr=f1.Real+f2.Realletci=f1.Imaginary+f2.Imaginary           {Real=cr ; Imaginary=ci}
staticmember (-) (f1 : Complex, f2 : Complex) =letcr=f1.Real-f2.Realletci=f1.Imaginary-f2.Imaginary            {Real=cr ; Imaginary=ci}
overridethis.ToString() =if (this.Imaginary=0.) thenthis.Real.ToString()
elsethis.Real.ToString() +"+"+this.Imaginary.ToString()+"i"

   从数学上来说,复数(Complex)具有一个实部(Real)和一个虚部(Imaginary) ,这里的话,用float类型来代表每个部分的数值类型。其中的static member定义了一个静态成员方法,但它的函数名是一个操作符,可实现自定义操作符功能。这里简单的定义了一个复数的加法和减法操作。并override重写了ToString方法。最后,我们用如下代码段进行自定义操作符测试:

letc1= { Real=3. ; Imaginary=5. }
letc2= { Real=2. ; Imaginary=3. }
letc3=c1+c2letc4=c1-c2printfn"(%s) + (%s) = %s" (c1.ToString()) (c2.ToString()) (c3.ToString())
printfn"(%s) - (%s) = %s" (c1.ToString()) (c2.ToString()) (c4.ToString())

   运行此示例,结果如下:

(3+5i) + (2+3i) =5+8i(3+5i) - (2+3i) =1+2i

  最后,再给出一个根据官方文档示例修改的自定义操作符:

letrechcfab=ifa=0.thenbelifa<bthenhcfa (b-a)
elsehcf (a-b) b//分数typeFract=       {
fz : float//分子fm : float//分母       }
staticmember (+) (f1 : Fract, f2 : Fract) =letfz=f1.fz*f2.fm+f2.fz*f1.fmletfm=f1.fm*f2.fmletcf=hcffzfm          { fz=fz/cf; fm=fm/cf }
staticmember (-) (f1 : Fract, f2 : Fract) =letfz=f1.fz*f2.fm-f2.fz*f1.fmletfm=f1.fm*f2.fmletcf=hcffzfm           { fz=fz/cf; fm=fm/cf }
staticmember (*) (f1 : Fract, f2 : Fract) =letfz=f1.fz*f2.fzletfm=f1.fm*f2.fmletcf=hcffzfm          { fz=fz/cf; fm=fm/cf }
staticmember (/) (f1 : Fract, f2 : Fract) =letfz=f1.fz*f2.fmletfm=f2.fz*f1.fmletcf=hcffzfm          { fz=fz/cf; fm=fm/cf }
overridethis.ToString() =if (this.fm=1.)
thenthis.fz.ToString()
elsethis.fz.ToString() +"/"+this.fm.ToString()

执行测试代码示例如下:

letf1= { fz=2.; fm=5.}
letf2= { fz=1.; fm=6.}
letf=f1+f2printfn"(%s) + (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString())
letf=f1-f2printfn"(%s) - (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString())
letf=f1*f2printfn"(%s) * (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString())
letf=f1/f2printfn"(%s) / (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString())

执行示例结果如下:

(2/5) + (1/6) =17/30(2/5) - (1/6) =7/30(2/5) * (1/6) =1/15(2/5) / (1/6) =12/5
相关文章
|
5月前
运算符有哪些?优先级是怎么样的?转换数据类型的方法?(最少4种)
运算符有哪些?优先级是怎么样的?转换数据类型的方法?(最少4种)
46 0
|
7月前
|
Java API
使用Lambda表达式实现函数映射和过滤
使用Lambda表达式实现函数映射和过滤
48 1
|
8月前
|
C#
赋值组合运算符
赋值组合运算符
52 1
|
8月前
|
C#
C#动态查询:巧用Expression组合多条件表达式
在C#中,利用`Expression`类和`AndAlso`、`OrElse`方法,可以组合两个`Expression&lt;Func&lt;T, bool&gt;&gt;`以实现动态多条件查询。该方法通过构建表达式树,方便地构建复杂查询。示例代码展示了如何创建表达式树,分别检查年龄大于等于18和姓名为&quot;John&quot;的条件,并使用`AndAlso`组合这两个条件,最终编译为可执行的委托进行测试。
352 1
|
8月前
|
C语言
逻辑操作符
条件操作符(三目操作符)是C语言中唯一的三元运算符,形式为:表达式1 ? 表达式2 : 表达式3。如果表达式1为真,执行并返回表达式2的结果;否则,执行并返回表达式3的结果。示例和练习展示了如何使用此操作符来比较和输出两个数中的较大值。
47 1
|
8月前
|
Python
什么是语句?什么是表达式?怎么区分?
编程语言中的语句和表达式是基础概念。语句是执行操作或命令的代码行,如Python的`print("Hello, World!")`,通常以换行符结束。表达式则表示值或计算过程,如`2 + 2`,可赋值给变量或用于计算。语句侧重于执行动作,表达式侧重于计算值。表达式可含运算符、变量等,而语句由主语和谓语构成。示例中,`x = 10`和`print("Hello, World!")`是语句,`y = x + 5`和`result = a * b + c`是表达式。
|
索引
操作符之关系操作符,逻辑操作符,条件操作符,逗号表达式,下标引用操作符,函数调用操作符,访问结构体成员操作符
操作符之关系操作符,逻辑操作符,条件操作符,逗号表达式,下标引用操作符,函数调用操作符,访问结构体成员操作符
|
数据库
机房重构—在应使用条件的上下文(在 ‘where‘ 附近)中指定了非布尔类型的表达式
在应使用条件的上下文(在 ‘where‘ 附近)中指定了非布尔类型的表达式
264 0
|
存储 Java
基础二:操作符
基础二:操作符
100 0
三元操作符类型的转换规则:
三元操作符类型的转换规则:
102 0