2010-03-25 14 views

Respuesta

42

Si desea utilizar el motor # formateado de la F (y evitar la aplicación de la misma cosa usted mismo), puede utilizar las funciones F # de impresión, tales como printfn. Se le puede dar un especificador de formato para imprimir una lista completa (usando F # formato) o imprimir sólo unos primeros elementos (lo que ocurre cuando se llama ToString):

> printfn "%A" [ 1 .. 5 ];; // Full list using F# formatting 
[1; 2; 3; 4; 5] 

> printfn "%O" [ 1 .. 5 ];; // Using ToString (same as WriteLine) 
[1; 2; 3; ... ] 

Si desea utilizar Console.WriteLine (u otro. método NET) por alguna razón, también se puede utilizar sprintf que se comporta de manera similar a printf, pero devuelve la cadena con formato como el resultado:

Console.WriteLine(sprintf "%A" list) 

la ventaja de utilizar printf o sprintf es que también se ocupa automáticamente con otros F # tipos (por ejemplo, si tiene un li st que contiene tuplas, uniones discriminadas o registros).

+4

+1 No sabía acerca de "% A" –

+5

Me di cuenta de que "% A" con una secuencia <'a> no imprimirá solo unos pocos elementos (luego elipses)) Usé Seq.toList para convertirlo en una lista. –

+1

% A no imprime toda la lista: 'printf"% A "[1 .. 500] ;;' se detiene en '100'. –

14

No, no es posible imprimir el contenido de una lista F # sin necesidad de utilizar un ciclo/bucle de todo tipo. Para imprimir cada elemento, debe enumerar cada uno de ellos.

En F # pesar de que no hay que hacer con un bucle sin embargo pero en cambio se puede hacer con un buen funcionamiento tubería

[1;2;3;4;5] |> Seq.iter (fun x -> printf "%d " x) 

Y como Julieta señaló que podía simplificar esto aún más con la aplicación parcial

[1;2;3;4;5] |> Seq.iter (printf "%d ") 
+11

'[1; 2; 3; 4; 5] |> Seq.iter (printf"% d ")' - w00t, currying :) – Juliet

+3

'f o x en [1; 2; 3; 4; 5] printf "% d" x' - De hecho creo que simple para bucle sería tan bueno como 'Seq.iter'. Por supuesto, depende, pero en algunas situaciones yo personalmente prefiero la solución directa (¿quizás más imperativa?). –

+1

Si no es posible, ¿significa que la respuesta de Tomás Petricek es incorrecta? – abatishchev

0

Una forma quizá más funcional de hacerlo:

let nums = [1;2;3;4;5;6] 
let concat acc x = acc + " " + (string x) 
let full_list = List.fold concat "" nums 
printfn "%s" full_list 
+0

Desafortunadamente, la concatenación de cadenas es una operación muy ineficiente en .NET (porque necesita copiar la cadena completa), por lo que puede tener un mal rendimiento para listas grandes. En .NET, la forma recomendada sería usar 'StringBuilder' (que es mutable y hace que la solución sea un poco menos _functional_). –

+0

Además, en versiones recientes de F #, 'List.fold_left' se llama' List.fold' y puede reemplazar 'string_of_int' con la función' string' sobrecargada. –

+0

Actualizado para que coincida con el comentario de Tomás. Este lenguaje ha estado cambiando tan rápido últimamente, es un poco difícil mantenerse al día. – TwentyMiles

7

En general, si desea cambiar como una forma un printf "% A" imprime sus objetos como una forma fsi.exe muestra valores fo su tipo, se puede aplicar el atributo StructuredFormatDisplayAttribute a su tipo:

[<StructuredFormatDisplayAttribute("PP {PrettyPrinter}")>] 
type Foo(a:string array) = 
    let pp = Array.mapi (fun i (s: string) -> sprintf "{idx: %d len: %d contents: '%s'}" i s.Length s) a 
    member x.PrettyPrinter = pp 

> let foo = Foo [|"one";"two";"three"|];; 
val foo : Foo = 
    PP [|"{idx: 0 len: 3 contents: 'one'}"; "{idx: 1 len: 3 contents: 'two'}"; 
     "{idx: 2 len: 5 contents: 'three'}"|] 

> printfn "%A" foo;; 
PP [|"{idx: 0 len: 3 contents: 'one'}"; "{idx: 1 len: 3 contents: 'two'}"; 
    "{idx: 2 len: 5 contents: 'three'}"|] 
val it : unit =() 
+0

Interesante. ¿La función de impresora bonita debe ser un miembro público? –

+0

@Joel - no es importante porque esa propiedad se obtiene mediante refection API – ssp

Cuestiones relacionadas