2012-05-13 14 views
6

Sto imparando F # e trovo che sto scrivendo cose che funzionano ma che non capisco del tutto. Ecco un esempioF # espressione lambda con più istruzioni

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 

I metodi getCredentials, casa, menzioni, messaggi, showHelp e clearAllSettings sono tutte funzioni semplici e fare quello che ci si aspetta. (Sì, è un client Twitter, non è che il nuovo demo 'Ciao Mondo'?)

La linea:

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

opere come voglio. Chiama getCredentials, quindi home, quindi cita, quindi messaggi

Dal mio punto di vista, il punto e virgola si comporta come un separatore di istruzioni. Non ho visto questo descritto prima. È quello che sta succedendo qui?

C'è un modo più idiomatico di scrivere questo (in altre parole, un programmatore esperto di F # rotola sul pavimento ridendo quando ha visto questo)?

Ulteriori informazioni: Il mio intento originale era quello di avere un elenco di azioni e quindi aggiungere azioni mentre scopro le opzioni. In C# di solito lo faccio con l'Elenco < Azione>(). La cosa del punto e virgola mi ha sorpreso perché originariamente ho provato a scriverlo come:

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

Ma al compilatore non piaceva.

+1

Beh, qualche ora di scavare intorno alla specifica la lingua rivela la risposta. È una forma della sintassi nota come sintassi verbosa. Ecco un link che lo descrive: http://msdn.microsoft.com/en-us/library/dd233199.aspx Mi sto ancora chiedendo se il mio approccio all'analisi degli argomenti della riga di comando è come F lo farebbe. –

risposta

3

quando si scrive:

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

il compilatore crea una lista con un solo elemento che è una funzione di tipo unit -> unit. S1 ; S2 è una composizione di sequenza quando S1 ha un tipo di unit e S1 e S2 vengono eseguiti in ordine e viene restituito il risultato di S2. Pertanto, tre funzioni home, mentions e messages hanno effettivamente la firma int -> unit.

Se si desidera creare un elenco di 4 funzioni diverse, dovrebbe essere:

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

Queste funzioni sono separate da spazi bianchi per evitare la confusione di utilizzare; come delimitatore di lista e composizione di sequenza.

Dal momento che il vostro esempio ha tutte le liste con una sola elementi, potrebbe essere semplificato molto:

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

Hai ragione signore. I miei idiomi in C# continuano a intralciarti. Grazie. –

+0

Solo una piccola correzione, | _ -> ... dovrebbe essere | args -> ... – Bernadette

+0

Grazie a @Bernadette, è stato corretto. – pad