2010-10-28 15 views
6

È possibile applicare parzialmente una funzione come bprintf e impedire che venga limitata in base al suo utilizzo iniziale?Mantenimento parziale della funzione generica

mi piacerebbe fare quanto segue:

let builder = new System.Text.StringBuilder() 
let append = Printf.bprintf builder 
append "%i" 10 
append "%s" string_value 

risposta

8

è possibile aggiungere esplicito formato argomento

let builder = new System.Text.StringBuilder() 
let append format = Printf.bprintf builder format 
append "%i" 10 
append "%s" "1" 
+0

Grazie. Qualcuno può spiegare perché questo funziona e l'applicazione parziale no? – Daniel

+10

Perché in .NET, le funzioni possono essere generiche e le variabili no. 'let append format =' descrive una funzione; 'let append =' descrive una variabile. –

12

L'aspetto di F # che sta causando questo si chiama restrizione valore. Si può vedere che se si immettono solo i due let dichiarazioni a F # Interactive (in modo che il compilatore non dedurre il tipo dal primo utilizzo):

> let builder = new System.Text.StringBuilder() 
    let append = Printf.bprintf builder ;; 

errore FS0030: restrizione Valore. Il valore 'append' è stato dedotto per avere il tipo generico val append: ('_a ->' _b) quando '_a:> Printf.BuilderFormat <' _b> O rendere gli argomenti a 'append' espliciti o, se si non intendo per essere generico, aggiungere un'annotazione di tipo.

C'è un excellent article by Dmitry Lomov dal team F # che lo spiega in dettaglio. Come suggerisce l'articolo, una soluzione è quella di aggiungere esplicita dichiarazione di parametro Tipo:

let builder = new System.Text.StringBuilder() 
let append<'T> : Printf.BuilderFormat<'T> -> 'T = Printf.bprintf builder 
append "%i" 10 
append "%s" "Hello" 

Questo funzionerà bene.

Problemi correlati