为什么函数内部允许"do"?

svi*_*ick 10 f# language-specifications

我注意到以下代码在VS 2013中编译并运行:

let f() =
    do Console.WriteLine(41)
    42
Run Code Online (Sandbox Code Playgroud)

但是在查看F#3.0规范时,我找不到任何提及do这种方式的用法.据我所知,do可以有以下用途:

  • 作为循环的一部分(例如),这不是这种情况.while expr do expr done
  • 内部计算表达式,例如:

    seq {
        for i in 1..2 do
        do Console.WriteLine(i)
        yield i * 2
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这不是这里的情况,f也不包含任何计算表达式.

    虽然让我困惑的是,根据规范,do应该遵循in.in由于轻量级语法,这应该是可选的,但是在此处添加它会导致编译错误("不完整表达式中的"意外令牌").

  • 模块或类中的语句.这也不是这里的情况,do它位于函数内部,不在模块或类中.

我也注意到,#light "off"代码没有编译("绑定中的Unexpected关键字'do'),但我没有找到任何可以在轻量级语法部分解释这一点的东西.

基于这一切,我会假设do在函数内部使用这种方式不应该编译,但确实如此.我是否错过了规范中的内容?或者这实际上是编译器或规范中的错误?

Dan*_*iel 7

MSDN上文档:

do结合使用而不定义函数或值来执行代码.

尽管规范不包含允许的地方的综合列表,但它只是一个断言为类型的表达式unit.一些例子:

if ((do ()); true) then ()
let x: unit = do ()
Run Code Online (Sandbox Code Playgroud)

通常省略.前面的每个例子都没有do.因此,do仅用于声明表达式是类型unit.