2013-01-22 7 views
8

F#のフレキシブルタイプアノテーションの目的は何ですか?私は、F#を勉強していると私は、柔軟なタイプ、またはより良いの目的を理解していない、私はこれを書い違いを理解することはできません

set TextOfControl (c : Control) s = c.Text <- s 

と、この書き込み:

set TextOfControl (c : 'T when 'T :> Control) s = c.Text <- s 

ControlSystem.Windows.Forms.Controlクラスです。

答えて

13

あなたの例では違いはありません。

let setText (c: Control) s = c.Text <- s; c 
let setTextGeneric (c: #Control) s = c.Text <- s; c 

let c = setText (TreeView()) "" // return a Control object 
let tv = setTextGeneric (TreeView()) "" // return a TreeView object 

#Control'T when 'T :> Controlの近道であること:戻り値の型が拘束されている場合は、違いを見始めます。サブタイプ用の汎用関数を作成するには、 Type constraintsが重要です。

例えば、

let create (f: _ -> Control) = f() 

let c = create (fun() -> Control()) // works 
let tv = create (fun() -> TreeView()) // fails 

let create (f: _ -> #Control) = f() 

let c = create (fun() -> Control()) // works 
let tv = create (fun() -> TreeView()) // works 
+1

+1の#文を記述しています。 –

7

F#関数の引数として値を直接渡すと、コンパイラは自動的に値をアップキャストします(関数がControlの場合は、TextBoxの値を与えることができます)。したがって、パラメータの型として柔軟な型を使用すると、大きな違いはありません。

機能は、例えば、リスト'T listを取る場合は、違いがあります:

// Takes a list of any subtype of object (using flexible type) 
let test1<'T when 'T :> obj> (items:'T list) = 
    items |> List.iter (printfn "%A") 

// Takse a list, which has to be _exactly_ a list of objects 
let test2 (items:obj list) = 
    items |> List.iter (printfn "%A") 

// Create a list of System.Random values (System.Random list) 
let l = [new System.Random()] 
test1 l // This works because System.Random is subtype of obj 
test2 l // This does not work, because the argument has wrong type! 
+0

はなぜlist'共変ではない 'のですか? – rightfold

関連する問題