演算子のオーバーロード
Midoliy|F#プログラミング

演算子のオーバーロードの概要
サンプルでみるオーバーロード

演算子のオーバーロードの概要


 F#では、クラスやレコード型、グローバルレベルで算術演算子をオーバーロードすることが可能です。この章では、算術演算子をオーバーロードする方法を紹介します。
// ------------------
// [ 構文 ]
// ------------------
// クラス/レコード型の算術演算子オーバーロード構文.
static member (operator-symbols) (parameter-list) =
    method-body

// グローバルレベルの算術演算子オーバーロード構文.
let [inline] (operator-symbols) parameter-list = function-body

 クラスの演算子に対するオーバーロードは静的(= static)である必要があります。+ や - などの単項演算子に対する演算子のオーバーロードでは、「演算子が単項演算子であり、二項演算子ではないこと」を示すために、operator-symbolに (~: チルダ) を指定する必要があります。次の例は単項演算子のオーバーロードの簡単なサンプルです。
static member (~-) (v: Vector)

 上記のように単項演算子に対して (~) を付与していることがわかります。
 算術演算子をオーバーロードすることでオリジナルの動作を定義することが可能となります。ただし、グローバルレベルの算術演算子をオーバーロードする際は影響範囲が広大となってしまうため、積極的には使用しないほうがよいでしょう。これは、F#が定義している算術演算子のデフォルト動作を変更することとほぼ同義であるため、実装した本人以外がコードを読んだときに「ハマる」可能性があります。現実的にはクラスの演算子オーバーロードくらいしか使わないと思いますし、そうであるべきです。やむを得ず、グローバルレベルでのオーバーロードをする際は詳細設計書などの真っ先に目にはいるものに明記しておくようにしましょう。


サンプルでみるオーバーロード


 ところで、クラスの演算子のオーバーロードはどういった場面で使うのでしょうか?それはクラス自体を、さも数値などの値かのように扱いたいときに使用します。以下はベクトルを表すVectorクラスを使ったサンプルです。


 サンプルからわかるように、演算子のオーバーロードを定義することで、通常では許容されていない演算をさせることが可能となります。今回の例で言うならば、普通ではスカラ型の値とVector型の値の掛け算は(デフォルトでは定義されていないため)許されていませんが、自分できちんと定義してあげることで機能するようになります。
 クラスを利用する際は演算しのオーバーロードを利用することもそこそこあると思うので、覚えておくとよいでしょう。