定义样式首选项

时间:2017-10-06 08:35:05

标签: f#

F#定义的首选样式是什么?

我正在学习的book经常使用以下风格:

assertTrue($count === 1)

另一方面,当我在网上查找信息时,最有可能遇到以下情况:

let foo = fun x y -> 
    let aux1 = fun z -> z * 2 
        in aux1 x + 
    let aux2 = fun q -> q * 3 
        in aux2 y;;

Guide我找不到关于它的参考。这是一个超越“纯粹的风格”的问题吗?这两种方法背后有效率影响吗?

您的经验表明了什么?

2 个答案:

答案 0 :(得分:4)

作为一般规则,F#函数定义倾向于执行以下两种操作之一:

  1. 定义尽可能少的类型(let foo x y = ...)。大多数功能都是这种情况。或...

  2. 明确定义每个参数的类型和返回类型let foo (x : int) (y : int) : int = ...

  3. 样式#2很少见,而且我经常看到它是明确属于模块API的函数,并且还有///个注释来提供文档。但是,对于内部函数,通常使用无类型变体,因为F#的类型推断效果很好。

    此外,正如s952163在评论中指出的那样,in关键字几乎不再使用,因为#light样式使其不必要。我希望看到您的示例代码在现代F#样式中编写如下:

    let foo x y =
        let aux1 z = z * 2
        let aux2 q = q * 3
        (aux1 x) + (aux2 y)
    
    除非您要在F#Interactive控制台中输入,否则

    不需要;;。如果您正在使用VS Code + Ionide,并突出显示代码段并按 Alt + Enter 将其发送到F#Interactive,那么您不需要任何;;隔离因为Ionide会自动添加它们。

答案 1 :(得分:1)

我发现有证据表明第一种风格,即使今天是非传统风格,也与cur and和匿名功能有着内在的联系。

Currying是F#的强大特性,我记得,每个函数都只能使用一个参数。例如:

let add x y = x + y 
val add: int -> int -> int

签名被解释为 add 是一个函数,它将两个整数作为输入并返回一个整数。 当编译时间到来时,该函数被解释为:

let add2 = fun x -> fun y -> x + y
val add2: int -> int -> int

其中val add2: int -> int -> int在语义上等同于val add: (int -> (int -> int))

通过向add2提供参数,例如6,它返回fun y -> 6 + y,这是另一个等待其参数的函数,而x被{6替换1}}。 Currying意味着每个参数实际上都返回一个单独的函数:这​​就是为什么当我们调用只有少数参数的函数时会返回另一个函数。

如果我得到了正确的话,第二个例子let add x y = x + y的更常见的F#语法可以被认为是上面显示的显式currying风格的语法糖。