2013-11-28 10 views
10

TL; DR: F#コンパイラはdetermined by Eugene Fotinexpanded upon by Gene Belitskiとして、int operatorこの文脈でintを解釈します。最も良い回避策は、System.Int32.MaxValueまたは以下に説明するような一意のエイリアスを使用することです。F#int.MaxValueは「有効な定数式ではありませんが、System.Int32.MaxValueは?


次のレコードタイプ考えてみましょう:

type User = { 
    Username : string 
} 

を私はUsernameは3文字以上の長になりたいので、私はStringLength属性を使用します。そこには、最大長はありませんので、私はint.MaxValueに設定します。

type User = { 
    [<StringLength(int.MaxValue, MinimumLength=3)>] 
    Username : string 
} 

これは私に次のエラーを与える:私は代わりにSystem.Int32を使用する場合

This is not a valid constant expression or custom attribute value.

すべてが桃です:

type User = { 
    [<StringLength(System.Int32.MaxValue, MinimumLength=3)>] 
    Username : string 
} 

別名intの場合はコンパイルされます。

type User = { 
    [<StringLength(num.MaxValue, MinimumLength=3)>] 
    Username : string 
} 
and num = int 

または完全にタイプを修飾:

type User = { 
    [<StringLength(Microsoft.FSharp.Core.int.MaxValue, MinimumLength=3)>] 
    Username : string 
} 

私はF#のソースとint is defined exactly as you would expectでチェック:

type int32 = System.Int32 
// Then, a few lines later… 
type int = int32 

何が起こっていますか?私は、F#プリミティブ型は、ほとんどのコンテキストで他の型と互換性があると仮定しましたが、私のメンタルモデルから何かが欠落しているように見えます。

答えて

11

:フルネームの

  • 機能int:'T->intMicrosoft.FSharp.Core.Operators.int
  • type int = int32のフルネームのフルネームMicrosoft.FSharp.Core.int
  • type int<'Measure> = intMicrosoft.FSharp.Core.int<_>
この仕組みをデモするために210

一つの方法は、次のシナリオのようになります。私たちはFSIに

int;; 

を入力した場合、我々は、他の言葉で

val it : (int -> int) = <fun:[email protected]> 

ような何かを得るでしょう、それができない機能ですMaxValueプロパティが関連付けられています。同じは、int32に適用されます

> int.MaxValue;; 

int.MaxValue;; 
----^^^^^^^^ 

... error FS0039: The field, constructor or member 'MaxValue' is not defined 

れ、式の文脈で使用されているときは、FSIによって、署名が(int -> int32)の別の関数として推論されます。そう

場所を持っていない、それはこの文脈int

type num = int 

に来るとき今System.Int32のタイプ名の略語と推定されるので、numは、同様のタイプの略語ですが、今曖昧に名前を付け、あなたが明示的に型エンティティを参照Microsoft.FSharp.Core.int使用する場合num.MaxValueは、

> num.MaxValue;; 
val it : int = 2147483647 

最後FSIに与えて、我々はそれがあることを期待するものを正確に推定され、何もありませんあいまいさがあるため、期待どおりに動作します。

あなたのユースケースに戻って、属性パラメータを使用してください。この文脈では、intは明示的にまたは間接的に別の解釈を設定しない限り、引数値を提供する式の一部として型推論で扱われます。

5

変換関数intとして属性のパラメータにintを処理するコンパイラのように見えます。

F#型推論が偶然 intの場合のいずれであってもよい、同じ名前、異なる構文エンティティと異なるコンテキストでどのように動作するかだ
+0

あなたはそうです、それは起こっていることです。それはなぜですか? F#文法の何か、私は思いますか? –

関連する問題