Overloaded inline operators in F#: ( |+| )

前端 未结 2 1654
感情败类
感情败类 2020-12-04 02:51

I\'m trying to define an overloaded operator, e.g. |+|, as the following:

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


        
2条回答
  •  醉话见心
    2020-12-04 03:13

    If you're defining an operator that behaves like + then I think the best design is to define an operator that returns a value of the same type as is the type of its arguments. This means that I would change the operator to return IMeasurable instead of 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)
    

    This will make the operator definition more uniform and easier to use. The code you wanted to write will now work (returning IMeasurable), but you can also use 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 (|+|)
    

    That said, if you really want to overload an operator that is defined using let and you cannot add it to a type as static member (because you cannot modify the type), then you'll need to use the trick that Gustavo describes

提交回复
热议问题