測量単位

F#の中でわかりやすく、それでいてクールな機能が測量単位というものです。メートルとかキログラムとか好きな単位を作成して指定できます。

open NUnit.Framework

[<Measure>]
type m

[<Measure>]
type kg

let calculateBMI (height : float<m>) (weight : float<kg>) =
weight / (height * height)

let printBMI (bmi : float<kg/m^2>) =
printfn "%O" bmi

[<Test>]
let ``test measure``() =
let height = 1.70<m>
let weight = 56.<kg>
let bmi = calculateBMI height weight
printBMI bmi

実行結果

19.3771626297578


単位のチェックをコンパイル時に行うため、例えば、下のような単位が付いていない値を(単位つきの引数を期待する)関数に渡すとコンパイルエラーになります。


calculateBMI 1.70 56.0
ちょっと残念なのは、実行時には単位の情報を取得できないところですね。

とはいえ、測量単位の機能は魅力的です。自分が想定するのは業務アプリですが、ほとんどのアプリでこのような機能が必要とされている(あると非常に便利になる)んじゃないかと思います。

追記

ドキュメントにもありますが、実行時に測量単位をもたないことでパフォーマンスに影響しないというメリットもあります。
http://msdn.microsoft.com/ja-jp/library/dd233243.aspx

自分が「残念」といったのは、もし実行時に取得できたらリフレクション使ってなんかおもしろいことができたかもしれないなぁといったくらいの意味です。