2012-05-13 35 views
6

Tôi đang học F # và thấy rằng tôi đang viết những thứ hoạt động nhưng tôi hoàn toàn không hiểu. Dưới đây là ví dụBiểu thức F # lambda với nhiều câu lệnh

let processArgs args = 
    match args with 
    | null 
    | [||]   -> [fun() -> getCredentials(); home 20; mentions 20; messages 20] 
    | [|"-h"|] 
    | [|"-?"|]  -> [showHelp] 
    | [|"-reset"|] -> [clearAllSettings] 
    | _    -> [fun() -> printfn "%s" (String.Join(" ", args))] 

[<EntryPoint>] 
    let main (args:string[]) = 
    try 
     let actions = processArgs args 
     List.iter (fun action -> action()) actions 
     0 
    finally 
     Console.ResetColor() 
     Console.CursorVisible <- true 

Phương thức getCredentials, home, mentions, messages, showHelp và clearAllSettings là tất cả các chức năng đơn giản và làm những gì bạn mong đợi. (Vâng, đó là một khách hàng twitter, mà không phải là mới 'Hello World' demo?)

Dòng:

[fun() -> getCredentials(); home 20; mentions 20; messages 20] 

công trình như tôi muốn. Nó gọi getCredentials, rồi về nhà, sau đó đề cập đến, sau đó nhắn tin

Từ quan điểm của tôi, dấu chấm phẩy hoạt động như một dấu tách câu lệnh. Tôi chưa từng thấy điều này được mô tả trước đây. Đó là những gì đang xảy ra ở đây?

Có cách viết thành ngữ nào hơn không (nói cách khác, một cuộn lập trình F # dày dặn trên sàn cười khi họ nhìn thấy điều này)?

Thông tin khác: Mục đích ban đầu của tôi là có danh sách tác vụ và sau đó thêm hành động khi tôi khám phá các tùy chọn. Trong C#, tôi thường làm điều này với Danh sách < Hành động>(). Điều bán dấu chấm phẩy làm tôi ngạc nhiên vì ban đầu tôi đã cố gắng viết nó như sau:

[getCredentials; home 20; mentions 20; messages 20] 

Nhưng trình biên dịch không thích nó.

+1

Vâng, một vài giờ đào bới xung quanh đặc tả ngôn ngữ cho thấy câu trả lời. Đó là một dạng cú pháp được gọi là cú pháp dài dòng. Đây là một liên kết mô tả nó: http://msdn.microsoft.com/en-us/library/dd233199.aspx Tôi vẫn tự hỏi nếu cách tiếp cận của tôi để phân tích các đối số dòng lệnh là cách F # 'ers sẽ làm điều đó. –

Trả lời

3

Khi bạn viết:

[fun() -> getCredentials(); home 20; mentions 20; messages 20] 

trình biên dịch tạo ra một danh sách với chỉ có một yếu tố mà là một chức năng của loại unit -> unit. S1 ; S2 là thành phần chuỗi khi S1 có loại unit và S1 và S2 được thực hiện theo thứ tự và kết quả của S2 được trả lại. Do đó, ba hàm home, mentionsmessages thực sự có chữ ký int -> unit.

Nếu bạn muốn tạo ra một danh sách 4 chức năng khác nhau, nó phải là:

[ getCredentials; // ; is optional 
    fun() -> home 20; 
    fun() -> mentions 20; 
    fun() -> messages 20 ] 

Các chức năng này được ngăn cách bởi khoảng trắng để tránh nhầm lẫn khi sử dụng; dưới dạng phân cách danh sách và thành phần chuỗi.

Từ ví dụ của bạn có tất cả danh sách chỉ với một yếu tố, nó có thể được đơn giản hóa rất nhiều:

let processArgs = function 
    | [||]   -> getCredentials(); home 20; mentions 20; messages 20 
    | [|"-h"|] 
    | [|"-?"|]  -> showHelp() 
    | [|"-reset"|] -> clearAllSettings() 
    | args   -> printfn "%s" (String.Join(" ", args)) 

[<EntryPoint>] 
let main (args:string[]) = 
    try 
    processArgs args 
    0 
    finally 
    Console.ResetColor() 
    Console.CursorVisible <- true 
+0

Bạn là đúng. Thành ngữ C# của tôi tiếp tục cản đường. Cảm ơn. –

+0

Chỉ cần chỉnh sửa nhỏ, | _ -> ... nên là | args -> ... – Bernadette

+0

Cảm ơn @Bernadette, nó đã được sửa. – pad

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