測定単位Units of Measure

F # の浮動小数点と符号付き整数値には、関連付けられた測定単位を含めることができます。これは通常、長さ、ボリューム、質量などを示すために使用されます。Floating point and signed integer values in F# can have associated units of measure, which are typically used to indicate length, volume, mass, and so on. 単位付きの数量を使用することにより、コンパイラは、算術リレーションシップの単位が正しいことを確認できます。これにより、プログラミングエラーを防ぐことができます。By using quantities with units, you enable the compiler to verify that arithmetic relationships have the correct units, which helps prevent programming errors.

構文Syntax

[<Measure>] type unit-name [ = measure ]

解説Remarks

前の構文では、 単位名 を測定単位として定義しています。The previous syntax defines unit-name as a unit of measure. 省略可能な部分は、以前に定義した単位に基づいて新しいメジャーを定義するために使用されます。The optional part is used to define a new measure in terms of previously defined units. たとえば、次の行では、メジャー cm (センチメートル) を定義しています。For example, the following line defines the measure cm (centimeter).

[<Measure>] type cm

次の行では、メジャー ml (milliliter) を3次 () として定義して cm^3 います。The following line defines the measure ml (milliliter) as a cubic centimeter (cm^3).

[<Measure>] type ml = cm^3

前の構文では、 measure は単位を含む数式です。In the previous syntax, measure is a formula that involves units. 単位が関係する数式では、整数の累乗がサポートされています (正と負)。単位間のスペースは、2つの単位の積、つまり * 単位の積を示すと同時に、 / 単位の商を示します。In formulas that involve units, integral powers are supported (positive and negative), spaces between units indicate a product of the two units, * also indicates a product of units, and / indicates a quotient of units. 逆数単位の場合は、負の整数の累乗を使用するか、または / 単位の数式の分子と分母を区別するを使用できます。For a reciprocal unit, you can either use a negative integer power or a / that indicates a separation between the numerator and denominator of a unit formula. 分母に複数の単位を指定する場合は、かっこで囲む必要があります。Multiple units in the denominator should be surrounded by parentheses. の後のスペースで区切ら / れた単位は、分母の一部として解釈されますが、の後に続く単位 * は、分子の一部として解釈されます。Units separated by spaces after a / are interpreted as being part of the denominator, but any units following a * are interpreted as being part of the numerator.

1つの単位式で1を使用すると、dimensionless の数量を示すことも、分子などの他の単位と組み合わせて使用することもできます。You can use 1 in unit expressions, either alone to indicate a dimensionless quantity, or together with other units, such as in the numerator. たとえば、レートの単位はとして書き込ま 1/s れます。ここで、は s 秒を示します。For example, the units for a rate would be written as 1/s, where s indicates seconds. かっこは、単位の数式では使用されません。Parentheses are not used in unit formulas. 単位の数式で数値変換定数を指定することはできません。ただし、単位を個別に指定して変換定数を定義し、単位チェックされた計算で使用できます。You do not specify numeric conversion constants in the unit formulas; however, you can define conversion constants with units separately and use them in unit-checked computations.

同じことを意味する単位の数式は、さまざまな方法で記述できます。Unit formulas that mean the same thing can be written in various equivalent ways. したがって、コンパイラは、単位の数式を一貫性のある形式に変換します。これにより、負の値が reciprocals に変換され、単位が1つの分子と分母にグループ化され、分子と分母の単位が alphabetizes されます。Therefore, the compiler converts unit formulas into a consistent form, which converts negative powers to reciprocals, groups units into a single numerator and a denominator, and alphabetizes the units in the numerator and denominator.

たとえば、単位の数式 kg m s^-2m /s s * kg は両方ともに変換され kg m/s^2 ます。For example, the unit formulas kg m s^-2 and m /s s * kg are both converted to kg m/s^2.

浮動小数点式では測定単位を使用します。You use units of measure in floating point expressions. 浮動小数点数を関連する測定単位と共に使用すると、タイプセーフの別のレベルが追加され、弱く型指定された浮動小数点数を使用するときに、式で発生する可能性がある単位不一致エラーを回避するのに役立ちます。Using floating point numbers together with associated units of measure adds another level of type safety and helps avoid the unit mismatch errors that can occur in formulas when you use weakly typed floating point numbers. 単位を使用する浮動小数点式を記述する場合は、式の単位が一致している必要があります。If you write a floating point expression that uses units, the units in the expression must match.

次の例に示すように、山かっこで囲まれた単位の数式でリテラルに注釈を付けることができます。You can annotate literals with a unit formula in angle brackets, as shown in the following examples.

1.0<cm>
55.0<miles/hour>

数字と山かっこの間にスペースを入れないでください。ただし、次の例に示すように、などのリテラルサフィックスを含めることができ f ます。You do not put a space between the number and the angle bracket; however, you can include a literal suffix such as f, as in the following example.

// The f indicates single-precision floating point.
55.0f<miles/hour>

このような注釈は、リテラルの型をプリミティブ型 (など) から float 次元型 (この場合はなど) に変更し float<cm> float<miles/hour> ます。Such an annotation changes the type of the literal from its primitive type (such as float) to a dimensioned type, such as float<cm> or, in this case, float<miles/hour>. の単位注釈は <1> dimensionless quantity を示し、その型は、unit パラメーターを持たないプリミティブ型に相当します。A unit annotation of <1> indicates a dimensionless quantity, and its type is equivalent to the primitive type without a unit parameter.

測定単位の型は、浮動小数点型または符号付き整数型であり、追加の単位注釈が角かっこで示されます。The type of a unit of measure is a floating point or signed integral type together with an extra unit annotation, indicated in brackets. したがって、変換の種類を g (グラム) から (キログラム) に記述する場合は、次のように kg 型を記述します。Thus, when you write the type of a conversion from g (grams) to kg (kilograms), you describe the types as follows.

let convertg2kg (x : float<g>) = x / 1000.0<g/kg>

測定単位は、コンパイル時の単位チェックに使用されますが、実行時環境には保存されません。Units of measure are used for compile-time unit checking but are not persisted in the run-time environment. そのため、パフォーマンスには影響しません。Therefore, they do not affect performance.

測定単位は、浮動小数点型だけでなく、任意の型に適用できます。ただし、浮動小数点型、符号付き整数型、および10進数型のみが次元の数量をサポートします。Units of measure can be applied to any type, not just floating point types; however, only floating point types, signed integral types, and decimal types support dimensioned quantities. したがって、プリミティブ型と、これらのプリミティブ型を含む集計では、測定単位を使用するのが理にかなっています。Therefore, it only makes sense to use units of measure on the primitive types and on aggregates that contain these primitive types.

次の例は、測定単位の使用方法を示しています。The following example illustrates the use of units of measure.

// Mass, grams.
[<Measure>] type g
// Mass, kilograms.
[<Measure>] type kg
// Weight, pounds.
[<Measure>] type lb

// Distance, meters.
[<Measure>] type m
// Distance, cm
[<Measure>] type cm

// Distance, inches.
[<Measure>] type inch
// Distance, feet
[<Measure>] type ft

// Time, seconds.
[<Measure>] type s

// Force, Newtons.
[<Measure>] type N = kg m / s^2

// Pressure, bar.
[<Measure>] type bar
// Pressure, Pascals
[<Measure>] type Pa = N / m^2

// Volume, milliliters.
[<Measure>] type ml
// Volume, liters.
[<Measure>] type L

// Define conversion constants.
let gramsPerKilogram : float<g kg^-1> = 1000.0<g/kg>
let cmPerMeter : float<cm/m> = 100.0<cm/m>
let cmPerInch : float<cm/inch> = 2.54<cm/inch>

let mlPerCubicCentimeter : float<ml/cm^3> = 1.0<ml/cm^3>
let mlPerLiter : float<ml/L> = 1000.0<ml/L>

// Define conversion functions.
let convertGramsToKilograms (x : float<g>) = x / gramsPerKilogram
let convertCentimetersToInches (x : float<cm>) = x / cmPerInch

次のコード例は、dimensionless 浮動小数点数から次元浮動小数点値に変換する方法を示しています。The following code example illustrates how to convert from a dimensionless floating point number to a dimensioned floating point value. 1.0 で乗算するだけで、1.0 にディメンションが適用されます。You just multiply by 1.0, applying the dimensions to the 1.0. これは、のような関数に要約でき degreesFahrenheit ます。You can abstract this into a function like degreesFahrenheit.

また、dimensionless 浮動小数点数を予期する関数に次元値を渡す場合は、演算子を使用して、その単位をキャンセルするか、にキャストする必要があり float float ます。Also, when you pass dimensioned values to functions that expect dimensionless floating point numbers, you must cancel out the units or cast to float by using the float operator. この例では、 1.0<degC>printf dimensionless 数量を想定しているため、の引数としてをで除算し printf ます。In this example, you divide by 1.0<degC> for the arguments to printf because printf expects dimensionless quantities.

[<Measure>] type degC // temperature, Celsius/Centigrade
[<Measure>] type degF // temperature, Fahrenheit

let convertCtoF ( temp : float<degC> ) = 9.0<degF> / 5.0<degC> * temp + 32.0<degF>
let convertFtoC ( temp: float<degF> ) = 5.0<degC> / 9.0<degF> * ( temp - 32.0<degF>)

// Define conversion functions from dimensionless floating point values.
let degreesFahrenheit temp = temp * 1.0<degF>
let degreesCelsius temp = temp * 1.0<degC>

printfn "Enter a temperature in degrees Fahrenheit."
let input = System.Console.ReadLine()
let parsedOk, floatValue = System.Double.TryParse(input)
if parsedOk
   then
      printfn "That temperature in Celsius is %8.2f degrees C." ((convertFtoC (degreesFahrenheit floatValue))/(1.0<degC>))
   else
      printfn "Error parsing input."

次のセッション例は、からの出力とこのコードへの入力を示しています。The following example session shows the outputs from and inputs to this code.

Enter a temperature in degrees Fahrenheit.
90
That temperature in degrees Celsius is    32.22.

汎用単位の使用Using Generic Units

関連する測定単位を持つデータを操作するジェネリック関数を作成できます。You can write generic functions that operate on data that has an associated unit of measure. これを行うには、次のコード例に示すように、型パラメーターとしてジェネリック単位を使用して型を指定します。You do this by specifying a type together with a generic unit as a type parameter, as shown in the following code example.

// Distance, meters.
[<Measure>] type m
// Time, seconds.
[<Measure>] type s

let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y

let v1 = 3.1<m/s>
let v2 = 2.7<m/s>
let x1 = 1.2<m>
let t1 = 1.0<s>

// OK: a function that has unit consistency checking.
let result1 = genericSumUnits v1 v2
// Error reported: mismatched units.
// Uncomment to see error.
// let result2 = genericSumUnits v1 x1

汎用単位を使用した集計型の作成Creating Aggregate Types with Generic Units

次のコードは、ジェネリックである単位を持つ個々の浮動小数点値で構成される集計型を作成する方法を示しています。The following code shows how to create an aggregate type that consists of individual floating point values that have units that are generic. これにより、さまざまな単位で動作する1つの型を作成できます。This enables a single type to be created that works with a variety of units. また、1つの単位セットを持つジェネリック型が、異なる単位のセットを持つ同じジェネリック型とは異なる型であることを保証することで、ジェネリックユニットはタイプセーフを保持します。Also, generic units preserve type safety by ensuring that a generic type that has one set of units is a different type than the same generic type with a different set of units. この手法の基礎は、属性を Measure 型パラメーターに適用できることです。The basis of this technique is that the Measure attribute can be applied to the type parameter.

 // Distance, meters.
[<Measure>] type m
// Time, seconds.
[<Measure>] type s

// Define a vector together with a measure type parameter.
// Note the attribute applied to the type parameter.
type vector3D<[<Measure>] 'u> = { x : float<'u>; y : float<'u>; z : float<'u>}

// Create instances that have two different measures.
// Create a position vector.
let xvec : vector3D<m> = { x = 0.0<m>; y = 0.0<m>; z = 0.0<m> }
// Create a velocity vector.
let v1vec : vector3D<m/s> = { x = 1.0<m/s>; y = -1.0<m/s>; z = 0.0<m/s> }

実行時の単位数Units at Runtime

静的な型チェックには、測定単位が使用されます。Units of measure are used for static type checking. 浮動小数点値をコンパイルすると、測定単位が削除されるため、実行時に単位が失われます。When floating point values are compiled, the units of measure are eliminated, so the units are lost at run time. したがって、実行時の単位のチェックに依存する機能を実装しようとすることはできません。Therefore, any attempt to implement functionality that depends on checking the units at run time is not possible. たとえば、 ToString 単位を出力する関数を実装することはできません。For example, implementing a ToString function to print out the units is not possible.

コンバージョンConversions

単位を持つ型 (など) を、単位の float<'u> ない型に変換するには、標準変換関数を使用します。To convert a type that has units (for example, float<'u>) to a type that does not have units, you can use the standard conversion function. たとえば、 float 次のコードに示すように、を使用して、 float 単位を持たない値に変換することができます。For example, you can use float to convert to a float value that does not have units, as shown in the following code.

[<Measure>]
type cm
let length = 12.0<cm>
let x = float length

単位を含む値に単位なしの値を変換するには、適切な単位で注釈が付けられた1または1.0 の値を乗算します。To convert a unitless value to a value that has units, you can multiply by a 1 or 1.0 value that is annotated with the appropriate units. ただし、相互運用性レイヤーを記述する場合は、単位の値を単位の値に変換するために使用できる明示的な関数もいくつかあります。However, for writing interoperability layers, there are also some explicit functions that you can use to convert unitless values to values with units. これらは、 Fsharp.core プリミティブ モジュールにあります。These are in the FSharp.Core.LanguagePrimitives module. たとえば、単位なしからに変換するには、 float float<cm> 次のコードに示すように、 FloatWithMeasureを使用します。For example, to convert from a unitless float to a float<cm>, use FloatWithMeasure, as shown in the following code.

open Microsoft.FSharp.Core
let height:float<cm> = LanguagePrimitives.FloatWithMeasure x

F # コアライブラリの測定単位Units of Measure in the F# Core library

名前空間では、ユニットライブラリを使用でき FSharp.Data.UnitSystems.SI ます。A unit library is available in the FSharp.Data.UnitSystems.SI namespace. この例では、副名前空間のシンボル形式 ( m メーターの場合) UnitSymbols と、 meter サブ名前空間のフルネーム (メーターのような) の両方に SI 単位が含まれてい UnitNames ます。It includes SI units in both their symbol form (like m for meter) in the UnitSymbols sub-namespace, and their full name (like meter for meter) in the UnitNames sub-namespace.

関連項目See also