F# lambda函数体中的更多说明

F# lambda函数体中的更多说明,f#,f#-interactive,F#,F# Interactive,正如我所知,我能够用F#这样定义lambda函数 (fun arg -> arg * arg) 但我如何将该定义的主体扩展到多个表达式?在某些伪代码中,它可能如下所示: (fun arg -> { log "abcd" arg * arg }) 我需要它来做一些副作用。F#对空格和缩进敏感。代码块的嵌套取决于代码块向右缩进的方式 对于您的特定示例,为了在函数体中嵌套多个表达式,只需将它们缩进至少一个空格: let f1 = fun arg -> arg *

正如我所知,我能够用F#这样定义lambda函数

(fun arg -> arg * arg)
但我如何将该定义的主体扩展到多个表达式?在某些伪代码中,它可能如下所示:

(fun arg -> {
    log "abcd"
    arg * arg
})
我需要它来做一些副作用。

F#对空格和缩进敏感。代码块的嵌套取决于代码块向右缩进的方式

对于您的特定示例,为了在函数体中嵌套多个表达式,只需将它们缩进至少一个空格:

let f1 = fun arg -> arg * arg

let f2 = fun arg ->
    log "abcd"
    arg * arg
包含多个表达式的另一种方法是用分号分隔它们:

let f3 = fun arg -> log "abcd"; arg * arg
一般来说,在大多数情况下,分号可以用在F#中,而不是换行符

如果需要将此类多行lambda表达式用作另一个函数(例如,
List.map
)的参数,则可能需要将整个函数体括在括号中:

[1;2;3]
|> List.map ( fun x -> 
      log "abcd"
      x*x )
这不是因为缩进,而是因为没有括号,这将是一个语法错误的程序:关键字
fun
似乎是传递给
List.map
的参数,这是不可能发生的,因为
fun
是一个关键字。此规则同样适用于单行lambda表达式:

[1;2;3]
|> List.map ( fun x -> x*x )
可以使用“pipe left”操作符避免使用括号:

let squareAll = 
    List.map <| fun x -> 
        log "abcd"
        x*x

let squares = squareAll [1;2;3]
上述代码不会编译,因为编译器会将其理解为:

([1;2;3] |> List.map) 
<| fun x -> x*x
([1;2;3]|>List.map)
x*x
这是不正确的,因为List.map不是一个函数


实际上,最常见的是使用括号。

基本上就是这样,只要去掉括号就行了。请不要告诉初学者关于
非常好奇的内容。在Haskel中,等价的
$
操作符非常普遍<代码>@FyodorSoikin非常感谢您的专家级解释。对于我来说,记不起那种语言中的缩进敏感性也是一大耻辱。这是我正在学习的具有这种特点的第一种语言
([1;2;3] |> List.map) 
<| fun x -> x*x