2010-03-25 35 views

Trả lời

42

Nếu bạn muốn sử dụng công cụ định dạng F # tích hợp (và tránh tự mình thực hiện), bạn có thể sử dụng chức năng in F # chẳng hạn như printfn. Bạn có thể cung cấp cho nó một specifier định dạng để in toàn bộ danh sách (sử dụng F # định dạng) hoặc in chỉ là một vài yếu tố đầu tiên (mà sẽ xảy ra khi bạn gọi 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; ... ] 

Nếu bạn muốn sử dụng Console.WriteLine (hoặc khác. NET phương pháp) đối với một số lý do nào, bạn cũng có thể sử dụng sprintf mà ứng xử tương tự như printf, nhưng trả về chuỗi được định dạng như là kết quả:

Console.WriteLine(sprintf "%A" list) 

lợi ích của việc sử dụng printf hoặc sprintf là nó cũng tự động giao dịch với khác F # các loại (ví dụ nếu bạn có một li st chứa tuples, unions unions hoặc record).

+4

+1 Không biết về "% A" –

+5

Tôi nhận thấy rằng "% A" với seq <'a> sẽ không in chỉ một vài phần tử (sau đó elip). Tôi đã sử dụng Seq.toList để chuyển đổi nó thành một danh sách. –

+1

% A không in toàn bộ danh sách: 'printf"% A "[1 .. 500] ;;' dừng tại '100'. –

14

Không có nó không thể in các nội dung của một # danh sách F mà không sử dụng một chu kỳ/vòng lặp của các loại. Để in mọi phần tử, bạn phải liệt kê từng phần tử.

Trong F # mặc dù nó không cần phải được thực hiện với một vòng lặp dù nhưng thay vào đó có thể được thực hiện với một thao tác ống đẹp

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

Và như Juliet chỉ ra tôi có thể đơn giản hóa này hơn nữa với ứng dụng phần

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

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

+3

'f hoặc x trong [1; 2; 3; 4; 5] làm printf "% d" x' - Tôi thực sự nghĩ đơn giản cho vòng lặp sẽ chỉ tốt bằng 'Seq.iter'. Tất nhiên điều đó phụ thuộc, nhưng trong một số trường hợp, cá nhân tôi thích giải pháp đơn giản hơn (có thể là bắt buộc hơn). –

+1

Nếu không thể, điều đó có nghĩa là câu trả lời của Tomas Petricek là không chính xác? – abatishchev

0

Một cách có lẽ thêm chức năng để làm việc đó:

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

Thật không may, chuỗi nối là hoạt động rất kém hiệu quả trên .NET (vì nó cần phải sao chép toàn bộ chuỗi), vì vậy điều này có thể có hiệu suất kém cho các danh sách lớn. Trong .NET, cách được đề xuất sẽ là sử dụng 'StringBuilder' (có thể thay đổi và làm cho giải pháp hơi kém hơn một chút _functional_). –

+0

Ngoài ra, trong các phiên bản gần đây của F #, 'List.fold_left' được gọi là' List.fold' và bạn có thể thay thế 'string_of_int' bằng hàm' string' quá tải. –

+0

Cập nhật để phù hợp với bình luận của Tomas. Ngôn ngữ này đã thay đổi nhanh chóng gần đây, có một chút khó khăn để theo kịp. – TwentyMiles

7

Nói chung, nếu bạn muốn thay đổi như là một cách một printf "% A" in đối tượng của bạn như là một cách fsi.exe cho thấy giá trị fo của bạn loại, bạn có thể áp dụng StructuredFormatDisplayAttribute thuộc tính kiểu của bạn:

[<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

Thú vị. Chức năng máy in đẹp có cần phải là thành viên công cộng không? –

+0

@ Jelel - nó không quan trọng vì thuộc tính đó thu được bằng API tinh chỉnh – ssp

Các vấn đề liên quan