【问题标题】:Overloaded inline operators in F#: ( |+| )F# 中重载的内联运算符:( |+| )
【发布时间】:2012-10-19 10:08:42
【问题描述】:

我正在尝试定义一个重载的运算符,例如|+|,如下:

let inline ( |+| ) (m1 : #IMeasurable) (m2 : #IMeasurable) = m1.Measure + m2.Measure

问题是,我不能这样做:

let three = m1 |+| m2 |+| m3

因为没有为案例(m1 : int) (m2 : #IMeasurable) 定义运算符|+|。有没有办法重载这个运算符或使用静态类型约束来使上述表达式成为可能?有没有办法修改IMeasurable(我可以编辑),这样就可以了?还有什么可以让上述表达式起作用的吗?

谢谢。

【问题讨论】:

    标签: syntax f# operator-overloading


    【解决方案1】:
    type Overloads = Overloads with
        static member ($) (Overloads, m1: #IMeasurable) = fun (m2: #IMeasurable) -> m1.Measure + m2.Measure 
        static member ($) (Overloads, m1: int) = fun (m2: #IMeasurable) -> m1 + m2.Measure
    
    let inline ( |+| ) m1 m2 = (Overloads $ m1) m2
    

    未测试,因为我没有 IMeasurable,但它可以完成这项工作。

    【讨论】:

      【解决方案2】:

      如果您要定义一个行为类似于+ 的运算符,那么我认为最好的设计是定义一个返回与其参数类型相同类型的值的运算符。这意味着我将更改运算符以返回IMeasurable 而不是int

      type IMeasurable =
        abstract Measure : int
      
      let newMeasure m = 
        { new IMeasurable with 
            member x.Measure = m }
      
      let inline ( |+| ) (m1 : #IMeasurable) (m2 : #IMeasurable) = 
        newMeasure (m1.Measure + m2.Measure)
      

      这将使操作符定义更统一,更易于使用。你想写的代码现在可以工作了(返回IMeasurable),但你也可以使用Seq.reduce

      // Now you can add multiple measure values without issues
      let res = (newMeasure 2) |+| (newMeasure 3) |+| (newMeasure 4)
      
      // Moreover, you can also use `Seq.reduce` which would not work
      // with your original operator (because it has wrong type)
      let res = [newMeasure 2; newMeasure 3; newMeasure 4] |> Seq.reduce (|+|)
      

      也就是说,如果你真的想重载使用let 定义的运算符并且你不能将它作为静态成员添加到类型中(因为你不能修改类型),那么你需要使用技巧古斯塔沃描述的

      【讨论】:

      • 恐怕在这种情况下返回 IMeasurable 没有意义。
      • 嗯,如果返回 IMeasurabe 没有逻辑意义,那么您可能需要遵循 @Gustavo 的建议。虽然这可能意味着拥有一个将IMeasurable 转换为int 的简单函数,然后将标准+ 用于ints 将是一个不错的选择。自定义运算符很难发现,而像 m1.Measure + m2.Measure + m3.Measure 这样的东西不太长且易于编写和理解。
      猜你喜欢
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多