2

F# で測定単位を使用してベクトルを処理するモジュールを定義したとします。

module Vec

    [<Measure>]
    type m

    type Vector3<[<Measure>] 'a> =
        {
        X : float<'a>
        Y : float<'a>
        Z : float<'a>
        }

letを保持して変数を作成したいと思いますVector3。私は次のようなことができます:

let my_var : Vector3<m> = {X = 1.0<m> ; Y = 1.0<m> ; Z = 1.0<m>};

上記のような多くの割り当てを行う必要があるため、以前の構文を単純化する方法はありますか? 何かのようなもの:

let my_var : Vector3<m> = { 1.0,1.0,1.0} //this don't compile
let my_var : Vector3<m> = {1.0<m> ; 1.0<m> ; 1.0<m>} //this don't compile either

をお願いします:

  1. 単位指定(1.0<m>)を避けたいのですが可能ですか?m宣言から暗黙のうちに導出 できませんmy_var : Vector3<m>か?
  2. レコード フィールド名の使用は避けてください (2 番目の例のように)。レコードのフィールド名は、順序に基づいてコンパイラ自体で導出できませんか?
4

2 に答える 2

5

変数の型を自分で指定する必要はないと思います。型の推論は F# に任せてください。したがって、以下の宣言で十分です。

let my_var = {X = 1.0<m> ; Y = 1.0<m> ; Z = 1.0<m>}

レコードフィールド名を指定したくない場合(プログラムを明確にするのに良いと思います)、レコードをクラス(@Tarmilの回答のように)または素結合に変更できます。個人的には、パターン マッチングで簡単に使用できるので、互いに素な共用体の方が好きです。

type Vector3<[<Measure>] 'a> = Vector3 of float<'a> * float<'a> * float<'a>

let my_var1 = Vector3(1.0, 1.0, 1.0) // Vector3<1>
let my_var2 = Vector3(1.0<m>, 1.0<_>, 1.0<_>) // Vector3<m>
于 2011-11-23T12:05:52.870 に答える
4

計測単位指定(1.0)を避けたいのですが可能ですか? m は、宣言 my_var : Vector3 から暗黙的に導出可能ではありませんか?

実際には、1.0 は 1.0<1> と同等であるため、1 (無次元) 以外の尺度が期待されるコンテキストでは使用できません。

ただし、1.0<_> を使用して推論を使用することはできます。

レコード フィールド名の使用は避けてください (2 番目の例のように)。レコードのフィールド名は、順序に基づいてコンパイラ自体で導出できませんか?

私が考えることができる最も近いものは次のとおりです。

type Vector3<[<Measure>] 'a> =
    val X : float<'a>
    val Y : float<'a>
    val Z : float<'a>
    new(x, y, z) = { X = x; Y = y; Z = z }

これは、次のように使用できます。

let my_var = Vector3<m>(1.0<_>, 1.0<_>, 1.0<_>)
于 2011-11-23T11:41:25.470 に答える