我正在学习F#并发现我正在编写有用的东西,但我并不完全理解。这是一个例子
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
方法getCredentials,home,mentions,messages,showHelp和clearAllSettings都是简单的函数,并按照您的期望行事。 (是的,这是一个Twitter客户端,不是新的'Hello World'演示吗?)
该行:
[fun() -> getCredentials(); home 20; mentions 20; messages 20]
像我想要的那样工作。它调用getCredentials,然后调用home,然后提及,然后是消息
从我的角度来看,分号就像一个语句分隔符。我以前没见过这个。那是怎么回事?
有没有更惯用的写作方式(换句话说,一个经验丰富的F#程序员在他/她看到这个时会笑在地板上吗?)
更多信息:我最初的目的是获得一系列操作,然后在发现选项时添加操作。在C#中,我通常会使用List&lt;行动&gt;()。分号让我感到惊讶,因为最初我试着把它写成:
[getCredentials; home 20; mentions 20; messages 20]
但是编译器不喜欢它。
答案 0 :(得分:3)
当你写:
[fun() -> getCredentials(); home 20; mentions 20; messages 20]
编译器创建一个只包含一个元素的列表,该元素是类型unit -> unit
的函数。 S1 ; S2
是S1的类型为unit
时的序列组成,S1和S2按顺序执行,返回S2的结果。因此,home
,mentions
和messages
这三个函数实际上具有签名int -> unit
。
如果要创建4个不同功能的列表,应该是:
[ getCredentials; // ; is optional
fun () -> home 20;
fun () -> mentions 20;
fun () -> messages 20 ]
这些函数由空格分隔,以避免混淆使用;作为列表分隔符和序列组合。
由于您的示例包含仅包含一个元素的所有列表,因此可以简化很多:
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