I\'m trying to define an overloaded operator, e.g. |+|
, as the following:
let inline ( |+| ) (m1 : #IMeasurable) (m2 : #IMeasurable) = m1.Me
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
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
Not tested, since I don't have IMeasurable, but it may do the job.