2016-12-12 7 views
2

コンパイル時に をチェックするだけでなく、呼び出し側の式もコンパイルするように、式のパラメータを定義できます。チェックコードコンパイル時の見積もり構造

type A = { 
    a : int 
} 

type Checker() = 
    static member Check(e : Expr<int>) : ResultType = ... 

PropertyGet(..., PropertyGet (....), a)に似た実際の発現をもたらす

let a = { a = 1 } 
Checker.Check <@ a.a @> 

チェック入力し、明らかに次のよう

は、例を見ることができます。

そして今、いくつかの他の方法

let getInt (a:A) : int = a.a 

以下も

Checker.Check <@ getInt a @> 

をコンパイルしかし、どのように私は2番目の例では、コンパイルされることを防止しPropertyGet秒間のみを許可することができますか? (例として)。
私は実行時に式の構造を調べることができますが、私はコンパイル時間のチェックをしたいと思います。

+5

できません。これが重要な要件である場合は、引用符の代わりにコンビネータのライブラリを使用することをお勧めします。 –

+0

どのように役立つでしょうか? – robkuz

+1

コンビネータ(または生成するデータ型)が無効なデータの作成を許可しないようにすることができます。あなたが知っている、 "無効なデータを説明できないようにする"とそのすべて。 –

答えて

1

Fyodorがコメントで述べたように、コンパイル時に引用が特定の形になることを保証する方法はありません。これは非常に不幸ですが、すべての引用ベースの(または式ツリーベースの)ライブラリはこれ(特にLINQ)に苦しんでいます。あなたの要件が「プロパティのみ取得」であれば、おそらくこれをランタイムチェックとして残すことができます。

私が本当にこれを保証したいのであれば、おそらくF# Compiler Serviceを使ってみると、typed expression treeが得られます。その後、ツリー上を歩いてプロジェクトのすべての引用を見つけ、エラーを報告することができます(リンタープラグインとしていくつかの拡張可能な方法で行うことができます。

あなたはDSLの方向に行ってきましたならば、あなたは(パイプを使用して)、たとえば、a |> get "foo" |> get "bar"を書くことができ、またはa?foo?bar?演算子を使用して)が、その後、あなたがいないよりも悪いように思われ、名にチェックを失います見積もりの​​正しい形を確認することができます。

+0

型指定されていないバリアントは決して行くことができません。少なくとも2パスコンパイルではなく、通常のワークフローのコンテキストで話している場合。あなたはそれをどのように想像するかをスケッチすることはできますか? – robkuz

+0

@robkuz 2パスコンパイルのようなものが間違いなく必要です。しかし、これをFSharpLint(https://github.com/fsprojects/FSharpLint)の統合として行うことができ、これをVSプラグインとして使用すると、経験をよりよくすることができます。 –

関連する問題