2010-04-30 14 views
9

in F #, data la seguente classe:F errore # compilazione: tipo di applicazione imprevisto

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

Perché la seguente compilazione:

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

Mentre la seguente sarà non compilare:

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

Non sono sicuro, ma la rimozione del dalla chiamata al Bar risultati in nessun errore. –

+0

Vero, ma che effettivamente utilizza internamente System.Object. Se si dovesse utilizzare il tipo di <'t> come parte di alcuni test, sarebbe un po 'inutile. –

risposta

14

Sembra che fornire parametri di tipo quando il metodo di trattamento come valore di prima classe non è supportato. Ho controllato il F# specification e qui ci sono alcuni pezzi importanti:

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.

Se si specifica argomenti di tipo e gli argomenti, quindi il primo caso si applica, ma come si può vedere, la specifica richiede alcuni argomenti effettivi troppo. Non sono abbastanza sicuro di quale sia la motivazione alla base di questo, però.

In ogni caso, se si utilizza il parametro di tipo in qualsiasi parte del tipo di firma degli Stati, allora è possibile specificarlo utilizzando le annotazioni di tipo simile a questo:

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

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

D'altra parte, se non si utilizza il parametro type ovunque nella firma, quindi non sono del tutto sicuro del motivo per cui ne hai bisogno in primo luogo. Se ne avete bisogno solo di un po 'di elaborazione runtime, allora si può essere in grado di prendere la rappresentazione tipo di runtime come argomento:

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

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