与 fsharp 中的等于运算符进行比较

Jos*_*lez 3 f# f#-interactive

如果我有下一种类型:

type Color(r: float, g: float, b:float) =
  member this.r = r
  member this.g = g
  member this.b = b
  static member ( * ) (c1:Color, c2:Color) =
      Color (c1.r*c2.r, c1.g*c2.g, c1.b*c2.b)

  static member Zero = Color(0.0,0.0,0.0)
Run Code Online (Sandbox Code Playgroud)

我这样做:

let ca = Color(1.,1.,1.)
let cb = Color(1.,1.,1.)
ca = cb
Run Code Online (Sandbox Code Playgroud)

我应该获得true,但是通过脚本进行的 F# 交互却给了我false 相反,如果我定义为:

let ca = Color(1.,1.,1.)
let cb = ca
ca = cb
Run Code Online (Sandbox Code Playgroud)

它返回true 我尝试以这种方式比较定义类型的两个值是否做错了什么?我怎样才能得到正确的结果?

谢谢

Mar*_*ann 5

的OP定义Color是一个。类具有引用相等性默认这意味着只有当它们字面上是同一个对象(指向相同的内存地址)时它们才相等。

只有 F# 中的函数数据类型具有结构相等性。其中包括记录、受歧视的工会、列表和一些其他类型。

Color定义为记录会更惯用:

type Color = { Red : float; Green : float; Blue : float }
Run Code Online (Sandbox Code Playgroud)

这种类型内置了结构平等:

> let ca = { Red = 1.; Green = 1.; Blue = 1. };;

val ca : Color = {Red = 1.0;
                  Green = 1.0;
                  Blue = 1.0;}

> let cb = { Red = 1.; Green = 1.; Blue = 1. };;

val cb : Color = {Red = 1.0;
                  Green = 1.0;
                  Blue = 1.0;}

> ca = cb;;
val it : bool = true
Run Code Online (Sandbox Code Playgroud)

如果你想为类型定义乘法和零,你也可以这样做:

let (*) x y = {
    Red = x.Red * y.Red
    Green = x.Green * y.Green
    Blue = x.Blue * y.Blue }

let zero = { Red = 0.0; Green = 0.0; Blue = 0.0 }
Run Code Online (Sandbox Code Playgroud)

这使您能够编写,例如:

> let product = ca * cb;;

val product : Color = {Red = 1.0;
                       Green = 1.0;
                       Blue = 1.0;}
Run Code Online (Sandbox Code Playgroud)