2010-04-30 20 views
9

, aşağıdaki sınıf verilen:F # derleme hatası: F In # Beklenmeyen tip uygulama

type Foo() = 
    member this.Bar<'t> (arg0:string) = ignore() 

Neden şu derleme vermez: Aşağıdaki

let f = new Foo() 
f.Bar<Int32> "string" 

derlemek etmeyecek olsa:

let f = new Foo() 
"string" |> f.Bar<Int32> //The compiler returns the error: "Unexpected type application" 
+0

Emin değilim, ama çağrısından kaldırmanın herhangi yanlışlıkla sonuçları Bar: Eğer sadece bazı çalışma zamanı işleme için ihtiyaç varsa, o zaman bağımsız değişken olarak zamanı tür gösterimini almak mümkün olabilir. –

+0

Doğru, ancak bu etkili bir şekilde System.Object iç kullanımını sağlar. Bazı testin bir parçası olarak <'t> tipini kullanacak olursanız, biraz yararsız olacaktır. –

cevap

14

Yöntem, birinci sınıf bir değer olarak değerlendirilirken, tür parametrelerinin sağlanmasının desteklenmediği anlaşılıyor. Ben F# specification kontrol ve burada bazı önemli bit şunlardır:

14.2.2 Item-Qualified Lookup
[If the application expression begins with:]

  • <types> expr, then use <types> as the type arguments and expr as the expression argument.
  • expr, then use expr as the expression argument.
  • otherwise use no expression argument or type arguments.
  • If the [method] is labelled with the RequiresExplicitTypeArguments attribute then explicit type arguments must have been given.

Tür argümanlar ve argümanları belirtirseniz, daha sonra ilk vaka geçerlidir, ancak gördüğünüz gibi, şartname de bazı gerçek argümanlar gerektirir. Gerçi bunun arkasındaki motivasyonun ne olduğundan emin değilim. Eğer üye türünü imza yerde türü parametresi kullanırsanız

Neyse, o zaman böyle tip açıklamaları kullanarak belirtebilirsiniz:

type Foo() = 
    member this.Bar<´T> (arg0:string) : ´T = 
    Unchecked.defaultof<´T> 

let f = new Foo() 
"string" |> (f.Bar : _ -> Int32) 

Öte yandan, kullanmak yoksa imzanın herhangi bir yerinde type parametresi, o zaman neden ilk etapta ihtiyacın olduğundan emin değilim.

type Foo() = 
    member this.Bar (t:Type) (arg0:string) =() 

let f = new Foo() 
"string" |> f.Bar typeof<Int32>