如果您要定义一个行为类似的运算符,+
那么我认为最好的设计是定义一个返回与其参数类型相同类型的值的运算符。这意味着我会将运算符更改为 returnIMeasurable
而不是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
并且你不能将它作为静态成员添加到类型中(因为你不能修改类型),那么你需要使用 Gustavo 描述的技巧