次のように動作する演算子を定義している場合+
、最良の設計は、引数の型と同じ型の値を返す演算子を定義することだと思います。これは、演算子を次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
それを静的メンバーとして型に追加できない場合 (型を変更できないため)、Gustavo が説明するトリックを使用する必要があります。