【问题标题】:How to shadow a record in F# Program.fs?如何在 F# Program.fs 中隐藏记录?
【发布时间】:2021-11-15 22:39:48
【问题描述】:

我正在关注 F# 书籍 Get Programming with F# 并进入了关于阴影的部分。他们提供的最简单的例子似乎是不可能的,所以我想知道是否为 F# 6 阴影删除或更改了此语法?我还没有找到任何说明或如何做这本书提供的影子记录的任何内容。

type Address =
    { Street: string
      Town: string
      City: string }

let home = { Street = "123 Main Street"; Town = "The Town"; City = "The City" }
let home = { home with City = "Second City" }
let home = { home with City = "Third City" }

尝试构建时出现错误:Duplicate definition of value 'home'


编辑

所以在搜索了为什么这不起作用的答案但没有成功后,我尝试将上述内容放入这样的函数中:

let testFunction = 
    let home = { Street = "123 Main Street"; Town = "The Town"; City = "The City" }
    let home = { home with City = "Second City" }
    let home = { home with City = "Third City" }
    0

它工作得很好。所以我现在的问题是为什么阴影在函数内部起作用而不在外部起作用?是否存在与不在函数范围内发生的模块级别的范围冲突?

【问题讨论】:

  • 模块中的顶级定义那样没有意义。我的意思是,你为什么要这样做,目标是什么?不过它确实可以在脚本中工作。
  • 补充一点,它在脚本中工作的原因是它在检查脚本完成方面存在细微差别。正如您可能想象的那样,在脚本/回复中使用一堆顶级值进行迭代,这些值的定义会随着您的实验而改变,这是一个重要的场景。但对于实际程序中的顶级值而言,情况并非如此。
  • @FyodorSoikin 原因是我正在学习 F#,所以我想运行本书中的一个示例,到目前为止,它一直在 Program.fs 中,而不是更正确地分离出来。

标签: f# shadowing


【解决方案1】:

要为现有答案添加更多细节,有四种不同的情况。

局部定义。如果你在一个函数体内,你可以使用阴影,这在进行多步计算时非常有用:

let adjust index = 
  let index = max 0 index
  let index = min 100 index
  index

类内的本地定义。您同样可以在类内隐藏本地定义:

type A() = 
  let foo = 1
  let foo = 2
  member x.Foo = foo

脚本文件的顶层。如果您位于脚本文件的顶层 (something.fsx),那么您可以使用阴影。脚本文件的想法是手动运行它们,因此拥有多个不同版本很有用 - 您只需手动运行您想要的版本:

let test = calculation1 ()
let test = caluclation2 ()

模块中的顶级(源文件)。 阴影不起作用的唯一情况是当您位于模块(或.fs 文件中)隐式成为一个模块)。在一个模块中,定义是公共的,它们被编译为类的静态成员,因此也存在技术限制(不能有多个同名的类成员)。

module Constants = 
  let answer = 1
  let answer = 42 // error FS0037: Duplicate definition of value 

【讨论】:

    【解决方案2】:

    为什么阴影只限于函数体?

    可能有一些技术原因。但核心原因是 IMO:

    命名很难。阴影可以减轻痛苦,但可能会令人困惑。

    F# 还支持“刻度命名”(home') 以具有相似但不同的名称。这是一种更安全的阴影。

    【讨论】:

    • 技术原因是我来这里的原因,因为我找不到他们。不过,这也是有用的信息。感谢您的建议和见解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多