F#入门—Functional Programming(一)

F#的主要泛型是函数式编程。在命令式编程中,我们主要花时间在列出执行任务的每一步细节。在函数式编程中,我们主要关心做什么,而不是怎么做;函数式编程本质上是对计算的又一次抽象,它被抽象为计算什么而不是怎么计算。虽然函数式编程不是银弹,但是它能使编程更清晰,而且在例如并发编程上会更简单。

一般的函数式编程需要满足一下特征:

•Immutable data •Ability to compose functions •Functions can be treated as data •Lazy evaluation •Pattern matching

用函数的方式编程 Immutability(不变性)

在F#中并没有变量(variable)的概念,只有值(value);因为在函数式编程中,任何声明的值默认都是不变的。

如果一个函数会改变程序的状态,例如写一个文件或者改变了内存中的一个全局变量,这就别称为“副作用”(side effect)。副作用并不总是不好的,但是它是许多bug的根源。不变的变量能帮助写更安全的代码,因为我们不用操心我们不能改变的东西。

下面的代码分别用命令式和函数式代码实现算一组数的平方和:

let square x=x*x //命令式编程 mutable表示是变量 let imperativeSum numbers= let mutable total=0 for i in numbers do let x=square i total <- total+x total //函数式编程 let functionalSum numbers= numbers |> Seq.map [...]

F#入门--Fundamentals

函数

在F#中,定义函数和定义一个变量类似,只不过跟在函数名后面是函数的参数。下面定义了一个带一个整数参数的square函数,返回square:

> let square x=x*x;;

val square : int -> int

和C#不同,F#没有return关键字。因此在定义一个函数时,函数的最后一个表达式用来评估函数的返回。上图的int–>int,可以理解为“一个函数带了一个整数参数返回一个整数值”。还可以更复杂一点:

> let add x y=x+y;;

val add : int -> int -> int

上面代码的意思是:“一个函数带一个整型参数,这个参数返回一个函数,这个函数带一个参数并且返回一个整数。”(a  function  taking  an integer, which returns a function which takes an integer and returns an integer.)

类型推断(Type Inference)

由于F#是静态类型的语言,因此,以浮点数位参数调用上面的add方法,会提示编译错误:

> add 1.0 2.0;;

add 1.0 2.0;; —-^^^

[...]

F#入门

Hello World

任何语言的第一个程序:

printfn “Hello World!”

这就是一个完整的程序,就这么简单一句话!

复杂点的代码 open System [<EntryPoint>] let main (args : string[]) = if args.Length <> 2 then printfn “Error” let greeting, thing = args.[0], args.[1] let timeOfDay = DateTime.Now.ToString(“hh:mm tt”) printfn “%s, %s at %s” greeting thing timeOfDay // Program exit code 0 变量

F#使用let关键字定义变量并赋值;在F#中变量一旦初始化,值是不会改变的。在F#中,变量名是大小写敏感的,并且变量的开头只能是字母和下划线。

空格

在F#中,使用空格来定义代码块。例如在上面的代码中:

if args.Length [...]