带有多个语句的F#lambda表达式

时间:2012-05-13 16:50:15

标签: f#

我正在学习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]

但是编译器不喜欢它。

1 个答案:

答案 0 :(得分:3)

当你写:

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

编译器创建一个只包含一个元素的列表,该元素是类型unit -> unit的函数。 S1 ; S2是S1的类型为unit时的序列组成,S1和S2按顺序执行,返回S2的结果。因此,homementionsmessages这三个函数实际上具有签名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