F # lambda expression with several statements

I am learning F # and I believe that I am writing something that works, but which I do not quite understand. Here is an example

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 

The methods getCredentials, home, mentions, messages, showHelp and clearAllSettings are all simple functions and do what you expect. (Yes, this is a Twitter client, isn't this a new Hello World demo?)

Line:

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

works as i want. It calls getCredentials, then home, then mentions, then messages

From my point of view, the semicolon acts as a separator of statements. I have not seen this before. Is that what is going on here?

Is there a more idiomatic way to write this (in other words, will a seasoned F # programmer laugh on the floor when he sees this?)

Additional Information: My initial intention was to have a list of actions, and then add actions when I discover the parameters. In C #, I usually did this with List <Action> (). The semicolon surprised me, because initially I tried to write it like this:

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

But he did not like the compiler.

+6
source share
1 answer

When you write:

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

the compiler creates a list with only one element, which is a function of type unit -> unit . S1 ; S2 S1 ; S2 is the composition of the sequence when S1 is of type unit , and S1 and S2 are executed in order and the result S2 is returned. Therefore, the three functions home , mentions and messages really have the signature int -> unit .

If you want to create a list of 4 different functions, this should be:

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

These functions are separated by spaces to avoid confusion in use; as a list separator and sequence composition.

Since your example has all lists with only one element, it could be simplified:

 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 
+3
source

Source: https://habr.com/ru/post/915611/


All Articles