在F#中,顶级意味着什么?

Guy*_*der 7 f# scope shadowing toplevel

当人们谈论F#时,他们有时会提到这个词top-level;

什么top-level意思?

例如在之前的SO Q&A中

错误FS0037有时,非常混乱
定义模块VS.NET与F#Interactive F#中
命名空间和模块之间的区别是什么?
F#
F#和MEF中的 AutoOpen属性:导出函数如何执行此F#函数

该术语也会在评论中定期出现,但对于那些问答我没有提及.

关于范围的维基百科文章涉及到这一点,但没有F#的具体细节.

F#3.x规范仅规定:

11.2.1.1函数和值的Arity一致性

括号表示一个top-level函数,它可能是计算函数值的第一类计算表达式,而不是编译时函数值.

13.1自定义属性

例如,STAThread属性应该放在top-level"do"语句之前.

14.1.8类型变量的名称解析

对于top-level包含表达式和类型的任何成员或任何其他构造,它最初为空.

我怀疑这个术语在不同的语境中有不同的含义:范围,F#交互,阴影.

如果您还可以解释F#前身语言(ML,CAML,OCaml)的起源,我们将不胜感激.

最后,我不打算将答案标记为几天,以避免仓促答案.

Tom*_*cek 4

我认为顶级这个词在不同的上下文中有不同的含义。

一般来说,只要您有某种结构允许嵌套引用顶部未嵌套在其他任何内容中的一个位置,我就会使用它。

例如,如果您在表达式中说“顶级括号”,它将指的是最外面的一对括号:

((1 + 2) * (3 * (8)))
^                   ^
Run Code Online (Sandbox Code Playgroud)

当谈论 F# 中的函数和值绑定(和作用域)时,它指的是未嵌套在另一个函数内的函数。所以模块内的函数是顶级的:

module Foo = 
  let topLevel n = 
    let nested a = a * 10
    10 + nested n
Run Code Online (Sandbox Code Playgroud)

在这里,nested嵌套在 里面topLevel

在 F# 中,使用定义的函数和值let可以出现在模块内部或类内部,这使事情变得有点复杂 - 我想说只有模块内部的那些才是顶级的,但这可能只是因为它们默认是公共的。

关键字do的工作原理类似 - 您可以嵌套它(尽管几乎没有人这样做),因此顶层的doallowedSTAThread属性是不嵌套在另一个do或中的属性let

module Foo =
  [<STAThread>] 
  do
    printfn "Hello!"
Run Code Online (Sandbox Code Playgroud)

但是不允许嵌套do在另一个表达式中:

do
  [<STAThread>] 
  do 
    printfn "Hello!"
  printfn "This is odd notation, I know..."
Run Code Online (Sandbox Code Playgroud)