【问题标题】:comparing with equal operator in fsharp与 fsharp 中的相等运算符比较
【发布时间】:2015-12-12 02:44:54
【问题描述】:

如果我有下一个类型:

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)

我愿意:

let ca = Color(1.,1.,1.)
let cb = Color(1.,1.,1.)
ca = cb

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

let ca = Color(1.,1.,1.)
let cb = ca
ca = cb

它返回 true 尝试以这种方式比较定义类型的两个值,我做错了吗? 我怎样才能获得 true 作为结果?

谢谢

【问题讨论】:

    标签: f# f#-interactive


    【解决方案1】:

    Color 的 OP 定义是一个。默认情况下,类具有引用相等性,就像在 C# 中一样。这意味着它们只有在字面上是相同的对象(指向相同的内存地址)时才相等。

    只有 F# 中的函数数据类型具有结构相等性。其中包括记录、有区别的联合、列表和其他一些类型。

    Color 定义为记录会更惯用:

    type Color = { Red : float; Green : float; Blue : float }
    

    这种类型具有内置的结构相等性:

    > 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
    

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

    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 }
    

    这使您可以编写,例如:

    > let product = ca * cb;;
    
    val product : Color = {Red = 1.0;
                           Green = 1.0;
                           Blue = 1.0;}
    

    【讨论】:

      【解决方案2】:

      F# 为记录和联合实现自动成员比较,但不为类实现。如果您想拥有它并使用Color(r, g, b) 语法构造值,您可以使用单例联合。您将获得模式匹配作为奖励(请参阅我的 (*) 实现)。

      type Color =
        | Color of r: float * g: float * b: float
      
        member this.r = let (Color(r, _, _)) = this in r
        member this.g = let (Color(_, g, _)) = this in g
        member this.b = let (Color(_, _, b)) = this in b
      
        static member (*) (Color(r1, g1, b1), Color(r2, g2, b2)) =
          Color(r1 * r2, g1 * g2, b1 * b2)
      
        static member Zero = Color(0., 0., 0.)
      

      【讨论】:

        【解决方案3】:

        首先你应该阅读这个页面:

        http://blogs.msdn.com/b/dsyme/archive/2009/11/08/equality-and-comparison-constraints-in-f-1-9-7.aspx

        它很好地说明了F# 中的平等是如何工作的。

        至于您的具体问题,您正在研究参考平等和结构平等之间的区别。可以添加如下注解

        [<CustomEquality; CustomComparison>]
        

        您可以将重载添加到 Equals 方法 override x.Equals(other) 以进行成员比较

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-28
          • 1970-01-01
          • 2020-12-10
          • 2011-07-23
          • 2022-01-17
          • 1970-01-01
          • 2020-01-21
          • 2023-04-08
          相关资源
          最近更新 更多