F# 越用越喜欢
最近由于需要,把遗忘了几年的F#又捡了起来。说捡了起来,倒不如说是从头学习,原来学的早已经忘了!所谓学过,只不过看过一本《F# 语言程序设计》 (郑宇军 凌海风 编著 --清华大学出版社)。对于编程书看的再多,不做项目也是没用,也不能正真理解其思想,只能停留在表面。另外,长时间不用也就忘了,F#就是这样。这次该真正用了,于是又花了几周时间从头学起,不用不知道,一用吓一跳!
对于使用多年C#语言从事.NET面向对象开发的人员来说,F#这种函数编程极其不习惯,不光是语法上不习惯,整个概念上跟C#都不一样。要只是语法不一样就简单了,难就难在要转变一个人思维习惯,要转变一个人思维是多难的一件事情呀!但要学F#就得必须转变。
1、F# 与 C# 的比较
实际上,F#代码比C#的代码要精简很多,一般说来,对同样的一段程序,使用F#编写要比使用C#编写代码要短。比如,要做一个交换两个数的一个函数。
C#:
public void Swap( ref int a, ref int b)
{
int temp = a
a = b;
b = temp;
}
F#:
let Swap (a, b) = (b, a)
C#用了3行语句,F#只用了一行。
有关F# 与 C# 的比较请参阅:http://blogs.msdn.com/b/timng/archive/2010/04/05/f-object-oriented-programming-quick-guide.aspx
2、F#的最大特点
F#最大的一个特点是函数式编程,这跟面向对象编程很不一样。面向对象编程一切都一对象为原则,一切都以对象为基础,离开对象是万万不能的。函数式编程一切的基础都是函数,而且还可以是高阶函数。
下面是线性回归最小二乘法数据拟合的一个例子,输入参数是元组float * float:
let linearFit (data : (float * float) []) =
let xs, ys = Array.unzip data
let sumx, sumy = Array.sum xs, Array.sum ys
let sumx2 = Seq.sumBy (fun x -> x * x) xs
let sumxy = Seq.sumBy (fun (x, y) -> x * y) data
let m = (float data.Length)
let t = sumx2 / sumx
let a0 = (sumxy - t * sumy) / (sumx - t * m)
let a1 = (sumy - a0 * m) / sumx
fun x -> a0 + a1 * x
let ds = [| (-1.0, -5.0); (1.0, 2.5); (4.0, 12.5); (5.0, 16.0) |]
let f = linearFit ds
printfn "%A" (f 9.0)
由于linearFit函数最后一行返回的是一个线性函数:
fun x -> a0 + a1 * x
这样,可以使用这个线性函数f(x) = a0 + a1 * x
对于给定的x(比如 x = 9.0),可以求得f(x),例如:f(9.0) = 29.93956006
求最大值、最小值、累加,使用卷叠一次完成。假设我们需要求数组中最大值、最小值,并要完成所有元素的求和,这可能需要分几步来完成,但对于F#只需一步就能完成。
let agg (arr : float[]) =
Array.fold (fun (a, b, c) -> (max a x, min b x, c + x)) (-infinity, infinity, 0.0) arr
let x = agg [| 20.56; 78.15; 12.38; 6.21; 25.0; 0.75; 33.33; 66.67|]
F#另一大特点是异步和并行计算,这期不介绍,后期再介绍。
3、F#是C#的替代者吗?
现在是面向对象时代,面向对象编程成为主流,而F#是建立在.NET Framewok基础之上的,所以F#必然也具备了面向对象的特点。按理说,函数式编程比面向对象编程早很多年,F#既然是函数式编程,不应该有面向对象血统,但微软为了能充分利用广阔. 的NET资源,所以使F#也具备了面向对象特性,看下面代码:
type Student(id : string, name : string) =
let mutable age = 20
let mutable department = "数学系"
member s.Age
with get() = age
and set v = age <- v
member s.Department
with get() = department
and set v = department <- v
let s = new Student("1002001", "李明")
s.Age <- 24
Student是一个学生类,有年龄属性和系属性,那么这个类型,可以被C#调用。下面是C#代码使用F#的Student类的代码:
Student student = new Student();
student.Age = 24;
F#既有函数式编程的特点又有面向对象编程的特性,是不是F#就取代了C#了呢?答案不是的。应该说F#与C#是互补的关系,并不是取代的关系。使用C#实现的用F#基本都能实现。F#也能使用ADO.NET访问数据库,开发WinForm、ASP.NET WebForm程序、开发WPF程序,这些都没问题,但F#最善长的不是这些,而是科学计算或数值计算,就是说用F#实现一些算法比较合适,而不是开发界面和数据库等。如果用F#也做一些C#善长做额事情,那么F#就没有价值和意义了,何必还要新推出一套一样功能的F#呢?
4、F#目前的不足
F#适合做科学计算,这跟Matlab、R等这些用语言有相同的地方,由于历史的原因Matlab、R资源库非常丰富,而F#的资源库很很少,这一点没法跟Matlab、R相比。但F#可以使用.NET资源库,这样能缓解一些。目前,使用F#的人远没有C#、Java那样多,特别是国内,使用F#真正做项目的人少之又少,这也妨碍了F#的发展。
下面是一些F#的资源链接,希望对您有用:
http://msdn.microsoft.com/zh-cn/library/dd233154.aspx
http://msdn.microsoft.com/zh-cn/vstudio/hh388569.aspx
http://fsharp.org/community/projects/
http://fsharp.org/technical-groups/
http://fsharp.org/guides/math-and-statistics/index.html
http://fsharp.org/guides/machine-learning/index.html
http://clear-lines.com/blog/post/Support-Vector-Machine-in-FSharp.aspx
http://clear-lines.com/blog/category/quantitative-modeling.aspx