适当的F#绑定风格

时间:2016-06-11 15:07:26

标签: .net f#

''更为微妙的用途之一。 F#中的关键字是能够注释返回单位(aka语句)的表达式。例如,我经常在函数定义中这样做,以明确返回类型是单位,并指示编译器为我键入check this。例如:

let restart agent = do agent.Post Restart

然而,我不确定对“做什么”的主导作用是什么?关键字在F#社区中。

使用'做'的正确方法是什么?此示例中的关键字:

// Annotate each statement
let move source destination =
    do copy source destination
    do clear source

// Annotate the statements as one block
let move source destination =
    do
        copy source destination
        clear source

// Just annotate the "return" statement
let move source destination =
    copy source destination
    do clear source

// Perhaps don't annotate at all?
let move source destination =
    copy source destination
    clear source

1 个答案:

答案 0 :(得分:3)

为此,我很少看到F#代码中使用的do(引入unit表达式)。您描述的大多数类型检查已经在没有它的情况下自动执行,以FS0020警告未使用值的形式。

如果你只是写

let move source destination =
    copy source destination
    clear source

然后会发生以下三件事之一:

  • copyclear都返回unit

    在这种情况下一切都很好。

  • copy返回单元

    以外的类型

    在这种情况下,您将收到有关忽略值的FS0020警告:

      

    表达式copy source destination返回一个当前被忽略的int。如果您不需要此值,则应使用ignore函数明确忽略它,例如ignore (copy source destination)或将结果绑定到名称,例如let result = copy source destination

  • copy返回单位,clear返回unit以外的其他类型

    在这种情况下,没有警告,但move将与clear具有相同的类型,并且此差异将在move的呼叫网站上显示,您将在此处显示与上述相同的警告。

因此,do用于类型检查目的的效用相当有限:只有在最后一种情况下它会产生影响,通过使警告显示在原始行而不是强制您从{{{{{{{ 1}}的呼叫站点(或者可能 - 如果move是其范围中的最后一行 - 来自move的呼叫者呼叫站点,等等)。这首先很少会出错 - 如果move返回一个值(例如,一个布尔值表明清算是否成功),你绝对想要在调用中传播该信息链!

也就是说,这是一个非常简单的标记,(IMO)丝毫不会损害可读性,可以说是改进了它。考虑到F#社区对少数喜欢禁用轻量语法(clear)并手动输入分号和#light "off"令牌的用户没有问题,我无法想象end在任何地方扬起眉毛。