F# には、型指定されたコードと型指定されていないコードの両方の引用符があります。
違いは単なる便宜であり、型なしと型付きの引用はすべての場合にそれぞれに変換可能ですか、それとも型付きの引用、たとえば型なしの引用で可能なもののサブセットですか?
型付きでのみ機能し、型なしの引用では機能しない例はありますか?またはその逆の例はありますか?
F# には、型指定されたコードと型指定されていないコードの両方の引用符があります。
違いは単なる便宜であり、型なしと型付きの引用はすべての場合にそれぞれに変換可能ですか、それとも型付きの引用、たとえば型なしの引用で可能なもののサブセットですか?
型付きでのみ機能し、型なしの引用では機能しない例はありますか?またはその逆の例はありますか?
一般に、可能な限り型付き引用符を使用することをお勧めします。いつものように、これらの型を使用すると、実行時にエラーを引き起こす可能性がある正当性条件を静的に適用できます。検討:
let one = <@@ "one" @@>
// exception at runtime
let two = <@@ 1 + %%one @@>
とは対照的に
let one = <@ "one" @>
// compile time error: the type 'string' does not match the type 'int'
let two = <@ 1 + %one @>
さらに、型指定された引用符が次のような場合に、型指定されていない引用符に追加の型注釈が必要になることがあります。
// ok
let l = <@ [1] @>
let l2 = <@ List.map id %l @>
// fails at runtime (obj list assumed instead of int list)
let l = <@@ [1] @@>
let l2 = <@@ List.map id %%l @@>
// ok
let l = <@@ [1] @@>
let l2 = <@@ List.map (id:int->int) %%l @@>
ただし、引用符から非常に一般的なものを作成する場合は、型指定された引用符を使用できない場合があります (たとえば、型が静的に認識されていないため)。その意味で、型指定のない引用は柔軟性を高めます。
また、必要に応じて、型付き引用符と型なし引用符を簡単に変換できることにも注意してください (型付きから型なしに変換するにはExpr<_>
toをアップキャストします。逆の場合は to をExpr
使用Expr.Cast
します)。
通常、引用処理ライブラリの利用者は型付き引用を使用します。一方、引用処理の作成者は型指定のない引用を処理する必要があります。
つまり、(<@@ @@>)
演算子を使用して型なし引用符を直接作成することはあまりありません。ただし、 Quotations.Patternsモジュールなどのさまざまな F# コア ライブラリのアクティブ パターンを使用して引用を再帰的に処理するには、型指定されていない形式で引用を操作します。
Expr<'T>
拡張Expr
し、実際には多くの情報を追加しないことに注意してください。つまり、型付けされた引用は実際には幻想にすぎません。キャプチャされたすべてのメタデータはExpr
オブジェクト内にあり、実行時にのみ使用できます。