F# lambda expression with multiple statements
f#
Solution
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` is sequence composition when S1 has type of `unit`, and S1 and S2 are executed in order and S2's result is returned. Therefore, three functions `home`, `mentions` and `messages` actually have the signature `int -> unit`.
If you want to create a list of 4 different functions, it should be:
[ getCredentials; // ; is optional
fun () -> home 20;
fun () -> mentions 20;
fun () -> messages 20 ]
These functions are separated by whitespace to avoid confusion of using ; as list delimiter and sequence composition.
Since your example has all lists with only one elements, it could be simplified a lot:
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
Problem
I'm learning F# and finding I'm writing things that work but which I don't entirely understand. Here's 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, it's a twitter client, isn't that the new 'Hello World' demo?) The line: ``` [fun() -> getCredentials(); home 20; mentions 20; messages 20] ``` works like I want. It calls getCredentials, then home, then mentions, then messages From my perspective, the semicolon is acting like a statement separator. I haven't seen this described before. Is that what is going on here? Is there a more idiomatic way of writing this (in other words, would a seasoned F# programmer roll on the floor laughing when he/she saw this)? Further information: My original intent was to have a list of actions and then add actions as I discover options. In C# I would typically do this with List< Action >(). The semicolon thing surprised me because originally I tried to write it like: ``` [getCredentials; home 20; mentions 20; messages 20] ``` But the compiler didn't like it.