2012-06-21 19 views
6

En F #, ¿cómo curry una función que acepta una cantidad variable de parámetros?En F #, ¿cómo se curry las funciones de ParamArray (como sprintf)?

que tienen código como este ... (la función de registro es sólo un ejemplo, la aplicación exacta no importa)

let log (msg : string) = 
    printfn "%s" msg 

log "Sample" 

a que lo invocan en todo el código con las cadenas con formato sprintf, ex.

log (sprintf "Test %s took %d seconds" "foo" 2.345) 

Quiero ganarse la funcionalidad sprintf en la función de registro por lo que parece ...

logger "Test %s took %d seconds" "foo" 2.345 

He intentado algo así como

let logger fmt ([<ParamArray>] args) = 
    log (sprintf fmt args) 

pero no puedo averiguar cómo pasar el argumento ParamArray a la llamada sprintf.

¿Cómo se hace esto en F #?

+2

FYI - Usted pregunta por [expresiones de formato] (http://msdn.microsoft.com/en-us/library/ee340241) (que están escritos), no param arrays (que están sin tipo). – Daniel

Respuesta

7
let log (s : string) =() 
let logger fmt = Printf.kprintf log fmt 

logger "%d %s" 10 "123" 
logger "%d %s %b" 10 "123" true 
+0

Gracias, esto es más o menos lo que estaba buscando – Fendy

5

El comportamiento de las funciones de printf en F # es de alguna manera especial. Toman una cadena de formato, que especifica cuáles son los argumentos esperados. Puede usar Printf.kprintf como lo muestra desco para definir su propia función que toma una cadena de formato, pero no puede cambiar el manejo de las cadenas de formato.

Si quieres hacer algo como C# params (donde el número de argumentos es variable, pero no depende de la cadena de formato), entonces se puede utilizar ParamArray atributo directamente en un miembro:

open System 

type Foo = 
    static member Bar([<ParamArray>] arr:obj[]) = 
    arr |> Seq.mapi (fun i v -> printfn "[%d]: %A" i v) 

a continuación, puede llamar Foo.Bar con cualquier número de argumentos sin cadena de formato:

Foo.Bar("hello", 1, 3.14) 

Esto es menos elegante para el formato de cadenas, pero podría ser útil en otras situaciones. Desafortunadamente, solo funcionará con los miembros (y no con las funciones definidas con let)

Cuestiones relacionadas