【问题标题】:Shadowing in F#F#中的阴影
【发布时间】:2020-03-08 17:53:05
【问题描述】:

我想知道为什么 F# 允许阴影,尤其是在同一范围内。

我一直认为纯函数式编程结构中的值绑定类似于代数/数学中的赋值。

例如,

y = x + 1

将是一个有效的数学表达式,但

y = y + 1

不会。

但是,因为有阴影,

let y = y + 1

在 F# 中是一个完全有效的表达式。

为什么语言允许这样做?

【问题讨论】:

  • y = y + 1 不是一个有效的代数表达式,但在这里它类似于y' = y + 1。原来的y 因为阴影而无法访问。它实际上并没有改变y,而是重用绑定的名称。
  • 有趣的问题,但由于它是一个概念性的讨论问题,因此对于 cs.stackexchange.com 来说似乎更切题,而不是针对特定编程问题的 SO。

标签: math f# algebra purely-functional shadowing


【解决方案1】:

对此最正确的答案是因为创建者 Don Syme 认为添加到语言中是一个有用的功能。

不过,它有一些很好的用途。一种是使用 F# 样式的可选参数时:

type C() =
    member _.M(?x) =
        let x = Option.defaultValue 0 x
        printfn "%d" x

F# 可选参数是选项,它带来了高度的正确性和一致性。但是想象一个方法有 3 个或更多可选参数。必须重新绑定它们每个的值并为它们使用不同的名称会很烦人!这是阴影派上用场的一个领域。

在编写递归子例程时也很方便。考虑以下sum 的简单实现列表:

let mySum xs =
    let rec loop xs acc =
        match xs with
        | [] -> acc
        | h :: t -> loop t (h + acc)
    loop xs 0

由于阴影,我不需要为内部循环重新绑定 xs。因为它是通用的,xs 是我能想到的最好的名称,所以不得不为内部循环使用不同的名称会很烦人。

不过,阴影并不全是好消息。如果您不小心,来自open 声明的类型可能会隐藏先前声明的类型。这可能会令人困惑。 F# 编辑器工具可以将绑定与隐藏它们的绑定区分开来,但纯文本无法做到这一点。所以底线是:在 F# 中应用阴影时要仔细考虑。

【讨论】:

    猜你喜欢
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    相关资源
    最近更新 更多