1

Array.map2で理解できない何かに遭遇しました。

このコードを考えてみましょう:

type r1 = {
    v1 : int
    X : int
}

type r2 = {
    v1 : int 
    Y : int
}

let a1 = [|{v1=1;   X=1};   {v1=2;   X=2}|]   // val a1 : r1 [] ...
let a2 = [|{v1=100; Y=100}; {v1=200; Y=200}|] // val a2 : r2 [] ...

Array.map2 (fun x1 x2 -> (x1.X, x2.Y)) a1 a2   // works as expected
Array.map2 (fun x1 x2 -> (x1.v1, x2.v1)) a1 a2  // error FS0001: Type mismatch. Expecting a r2 [] but given a r1 [] 

両方のレコードにフィールドがありますv1。最後の行では、の値のタプルを取得しようとしていますがv1、さまざまなレコードタイプr1r2。異なるレコードで同じ名前のフィールドを選択しようとすると、エラーがスローされるようです。

x1どういうわけかそれはタイプでなければならないという結論にジャンプしますr2、なぜ2行目は2つのパラメータからタイプを推測しないのa1ですa2か?

編集

これで修正されますが、パラメーターからタイプを正しく取得することを期待します。

Array.map2 (fun (x1:r1) x2 -> (x1.v1, x2.v1)) a1 a2  // works
4

1 に答える 1

5

型チェッカーは左から右に機能するため、2 番目の例では競合を解決するのに十分な情報がありません。と はそれぞれとの一意のフィールドであるため、最初の例は問題.Xありません。.Yr1r2

とはいえ、この場合、レコード フィールドにアクセスする前に、パイプを使用して型を作成a1a2、型チェッカーで使用できるようにすることができます。

(a1, a2) ||> Array.map2 (fun x1 x2 -> (x1.v1, x2.v1))

一般に、固有のフィールドを含むレコード パターンを使用して正しいタイプを識別する必要があります。

Array.map2 (fun {v1 = a; X = _} {v1 = b; Y = _} -> (a, b)) a1 a2

または完全修飾フィールド名を指定します。

Array.map2 (fun {r1.v1 = a} {r2.v1 = b} -> (a, b)) a1 a2
于 2012-10-28T22:09:44.557 に答える