【问题标题】:Is there any difference between these two functions in F#?F#中这两个函数有什么区别吗?
【发布时间】:2014-12-28 07:48:29
【问题描述】:

在 F# 中编写这样的函数有什么区别...

let add x y = x + y

或者这个……

let add = fun x y -> x + y

当我查看 IL 时,它们似乎生成完全相同类型的 IL。它们当然“似乎”在做同样的事情,但从概念上讲,我觉得它们是不同的,第一个是函数声明,第二个是值声明,其中“值”是一个函数。

此外,如果我们能做一个更详细的例子..

这...

let add x = 
    let rnd = System.Random()
    let rnd = rnd.Next(100)
    x + rnd

...与此相比

let add = 
    let rnd = System.Random()
    let rnd = rnd.Next(100) 
    (fun x -> x + rnd)

这些示例遵循与前两个相同的原则,但是这两个的工作方式将大相径庭..

【问题讨论】:

  • System.Random 构成副作用,因此您会看到差异。

标签: function lambda f# closures


【解决方案1】:

在 F# 中,使用let 关键字绑定的每个表达式都是一个,包括函数;函数也是值。

因此,将函数fun x y -> x + y 绑定到add 是创建函数值的一种方法,但更惯用的方法是使用语法let add x y = x + y

但是,它们是完全等价的。

使用fun 关键字的语法主要用于将函数组合成高阶函数,例如当您想要过滤内联表达式时;例如:

numbers |> List.filter (fun i -> i % 2 = 0)

但是,您也可以使用像这样创建的函数作为返回值,就像在您的示例中一样。

正如您所说,这两个更复杂的示例并不等价,但以下示例与第一个更惯用的函数等价:

let add = 
    fun x ->
        let rnd = System.Random()
        let rnd = rnd.Next(100)
        x + rnd

这不是惯用的,所以我通常会像在 OP 中那样写它:

let add x = 
    let rnd = System.Random()
    let rnd = rnd.Next(100)
    x + rnd

虽然它们是等价的,但惯用的版本更短,因此,人们认为更具可读性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多