Mantenente funzione parzialmente applicata generica
-
27-09-2019 - |
Domanda
E 'possibile applicare parzialmente una funzione come bprintf
e impedire che essere limitato in base al suo uso iniziale?
Mi piacerebbe fare quanto segue:
let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder
append "%i" 10
append "%s" string_value
Soluzione
è possibile aggiungere esplicitamente formato argomento
let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"
Altri suggerimenti
L'aspetto di F # che sta causando questo è chiamato restrizione valore . Si può vedere che se si immettono solo due dichiarazioni let
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 di avere tipo generico val append: ( '_a ->' _b) quando '_a:> Printf.BuilderFormat <' _ b> O fare gli argomenti di 'append' esplicita o, se non si intende per che sia generica, aggiungere un tipo di annotazione.
C'è un eccellente articolo di Dmitry Lomov dal # team di F che spiega in dettaglio. Come suggerisce l'articolo, una soluzione è quella di aggiungere dichiarazione di parametro di tipo esplicito:
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.
Si sta incontrando la F # restrizione valore.
Ecco una buona spiegazione di alcune soluzioni: Comprendere F # valore errori di restrizione
Ecco un articolo piuttosto approfondito che spiega le ragioni dietro di esso: http://blogs.msdn.com/b/mulambda/archive/2010/05/01/value-restriction-in-f.aspx