F#基础教程 值与函数

    在F#里,值(Values)和函数(Functions)很难区分,因为函数也是值,在F#语法里他们是同一个概念。例如,在下面的代码里,第一行,把10分配给标识符n; 在第二行中,一个函数:add,并定义两个参数与运算。注意语法是多么的相似,唯一的区别是,函数名后有参数。第一行10是一个值,表达式a+b结果也是一个值。所以函数也代表一个值。另一个角度,不论是使用值还是函数,我们都只取它们的结果(值的结果即为值本身),所以本质上他们是相同的,对于使用他们的方法来说,结果的类型才是最重要的。

#light
let n = 10
let add a b = a + b
let addFour = add 4
let result = addFour n
printfn "result = %i" result

执行结果:

result = 14

     F#支持部分应用函数的方法(有时也被称为部分函数或currying函数(不要叫柯里化,这种直译最鳖足))。这意味着你不必声明函数的所有参数,如上例中第三行,通过一个单一的参数实现一个新的函数(编译器会将其翻译为let addFour b = add 4 b)。乍一看,这种思想好像索然无味并无实效,但它是函数式编程强大功能的一部分,你会看到这本书都在使用它(更多的部分方法将在后面章节介绍)。

  有时这种方式并不总是适当的。例如:如果函数有两个浮点参数,代表一个矢量点,部分化则不宜于它的表示,因为他们的组合代表了一个值。这时可以用括号包围函数的参数,并把它们用逗号分开,变成一个元组(tuple,也有人叫“情侣”),一个元组代表一个值,所以部分化是无法完成的。

#light
let sub (a, b) = a - b    //参数为一个元组
let subFour = sub 4      //部分化将失败

  换句话说,现在的sub只有一个参数,类型是一个元组,所以第三行的部分化将被提示参数类型错误。

  在一般情况下,可以部分化的函数优于使用元组的函数。这是因为可以部分化的函数比元组更为灵活,为用户提供更多使用它们的选择,在创建一个由其他程序员使用的库时更是如此。

  当你不需要直接返回一个值,如何在函数里计算中间点。在F#里,由空格控制。一个缩进代表中间计算的开始,let关键字代表一个中间点的计算,而一个表达式代表缩进的结束。如下例子,第三行、第四行是中间点的计算,而最后的表达式mid+a即为缩进的结束,亦为函数的结果。另一个角度,第三行、第四行也可以叫局部函数,更进一步,它们也可以有局部函数以实现更复杂的功能。不要质疑这种奇怪的表示,它们均来自经典的数学。在你习惯使用它们后,就会为之简洁明了而震撼。

#light
let halfWay a b =
    let dif = b - a
    let mid = dif / 2
    mid + a

printfn "(halfWay 5 11) = %i" (halfWay 5 11)
printfn "(halfWay 11 5) = %i" (halfWay 11 5)

    执行结果:
(halfWay 5 11) = 8
(halfWay 11 5) = 8

注意 #light 语法。这是为非 OCaml 程序员(F#最先为OCaml的.NET实现,但它已超越OCaml)开始使用 F# 而做的让步,放宽某些 OCaml 语言的语法要求,并使用大量空白定义代码块。虽然不一定必要,但对于那些原本使用 C#Visual Basic 的普通开发人员来说,它确实使语法更易于解析,因此它常出现在 F# 示例和公开的代码段中,并已成为事实上的 F# 编程标准。(未来版本的 F# 可能会将 #light 确定为默认语法,代替其他类似方法

posted @ 2011-11-21 18:06  银河系漫游指南  阅读(496)  评论(0编辑  收藏  举报