在 F# 中,顶级是什么意思?

In F# what does top-level mean?

当人们谈论 F# 时,他们有时会提到术语 top-level

top-level 是什么意思?

例如在之前的 SO 问答中


Defining Modules VS.NET vs F# Interactive
What the difference between a namespace and a module in F#?
AutoOpen attribute in F#
How to execute this F# function

该术语也经常出现在评论中,但对于那些问答,我没有提及它们。

scope 上的 Wikipedia 文章涉及到这一点,但没有针对 F# 的具体说明。

F# 3.x 规范仅声明:

11.2.1.1 函数和值的 Arity 一致性

The parentheses indicate a top-level function, which might be a first-class computed expression that computes to a function value, rather than a compile-time function value.

13.1 自定义属性

For example, the STAThread attribute should be placed immediately before a top-level “do” statement.

14.1.8 类型变量的名称解析

It is initially empty for any member or any other top-level construct that contains expressions and types.

我怀疑这个词在不同的上下文中有不同的含义: 范围,F# 交互,阴影。

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

最后,我不打算在几天内将答案标记为已接受,以免仓促回答。

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

一般来说,只要您有一些结构允许嵌套引用顶部的一个位置,但没有嵌套在其他任何位置,我就会使用它。

例如,如果您在表达式中说 "top-level parentheses",它将引用最外面的一对括号:

((1 + 2) * (3 * (8)))
^                   ^

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

module Foo = 
  let topLevel n = 
    let nested a = a * 10
    10 + nested n

这里,nested嵌套在topLevel内。

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

do 关键字的工作方式类似 - 您可以嵌套它(尽管几乎没有人这样做),因此允许 STAThread 属性的顶级 do 是不允许的嵌套在另一个 dolet:

module Foo =
  [<STAThread>] 
  do
    printfn "Hello!"

Bud 不允许嵌套在另一个表达式中的任何 do:

do
  [<STAThread>] 
  do 
    printfn "Hello!"
  printfn "This is odd notation, I know..."