2010-10-28 7 views
6

¿Es posible aplicar parcialmente una función como bprintf y evitar que se restrinja en función de su uso inicial?Mantenimiento de la función parcialmente aplicada genérico

me gustaría hacer lo siguiente:

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

Respuesta

8

puede agregar explícita formato argumento

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

Gracias. ¿Alguien puede explicar por qué esto funciona y la aplicación parcial no? – Daniel

+10

Porque en .NET, las funciones pueden ser genéricas y las variables no. 'let append format =' describe una función; 'let append =' describe una variable. –

12

El aspecto de F # que está causando esto se llama restricción valor. Se puede ver que si se introduce sólo los dos let declaraciones a F # Interactivo (para que el compilador no infiere el tipo desde el primer uso):

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

error FS0030: Valor restricción. Se ha inferido que el valor 'append' tiene apend genérico de tipo val ('_a ->' _b) cuando '_a:> Printf.BuilderFormat <' _b> O bien explicita los argumentos para 'anexar' o, si no tiene la intención de ser genérico, agregue una anotación de tipo.

Hay un excellent article by Dmitry Lomov del equipo F # que lo explica en detalle. Como sugiere el artículo, una solución es agregar declaración explícita de parámetro de tipo:

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

Esto funcionará bien.

Cuestiones relacionadas