2012-02-03 12 views
4

は、次の点を考慮bがOKである一方、タイプと機能

type T() = 
    member x.y = 4 

let a = 
    let fn() (k: T) =() 
    fn() 

let b = 
    let fn() (k: System.IO.Directory) =() 
    fn() 

aは失敗します。エラーメッセージがある:

値「」ジェネリックタイプのValを有することが推測されている:(「_a - >単位)場合」_a:> Tのいずれかが '明示的に引数を作りますか、それが一般的なものではない場合は、タイプ注釈を追加してください。

それを修正する理由とその方法は?

答えて

6

エラーメッセージ自体は正確にあなたが何をする必要があるかを説明します - 型注釈を追加します。

let a : T -> unit = 
    let fn() (k: T) =() 
    fn() 

あなたが最初の場所でエラーを参照してください理由は、コンパイラがの定義を一般化しようとするということですa(仕様のthis partを参照してください)、エラーメッセージに表示される奇数の署名になります。

bでこれを行う必要がない理由は、System.IO.Directoryが封印されているため、一般化する必要はありません。

1

aは定数のように見えますが、関数を返すため、値の制限があります。 はこの質問を見てください:それを解決するために

Understanding F# Value Restriction Errors

一つの簡単な方法は、aの定義に変数を追加しています。

let a x = 
    let fn() (k: T) =() 
    fn() x 

私はなぜ知らない、レコードの代わりに、クラスは、それがうまくいくT場合b

+0

しかし、定義に 'x'を追加すると、関数値から関数に' a'が変更されます。つまり、起動時に評価されません。詳細な説明は、[F#値、関数、およびその両方](http://blog.wezeku.com/2010/08/01/values-functions-and-bit-of-both)を参照してください。 –

0

の場合で、それが動作するいくつかの種類、と。しかし、いくつかの理由のために、あなたは、Tがクラスの場合は、コンパイラのためにそれを綴る

type T() = 
    member x.y = 4 

let a<'U when 'U :> T> = 
    let fn() (k: 'U) =() 
    fn() 

let test0 = a<T> (T()) // You can be explicit about T, 
let test1 = a (T())  // but you don't have to be. 

編集する必要があります。だから私は不気味よりこれでビットを果たし、そして、コンパイラはただの持つコンテンツであると思われますタイプの制限:

type T() = 
    member x.y = 4 

type S() = 
    member x.z = 4.5 

let a<'U when 'U :> S> = 
    let fn() (k: T) =() 
    fn() 

let test = a (T())  // Is OK 
let test = a<T> (T()) // Error: The type 'T' is not compatible with the type 'S' 

タイプSは、上記のコードで何とは何の関係もありませんが、まだコンパイラはちょうどあらゆる種類の制限を持って幸せです。

関連する問題