语言基础
#light(OCaml兼容)
F#源自OCaml,具有交互编译OCaml的能力,也就是可以不经修改即可编译简单的OCaml程序。这种能力也带来了令人讨厌的语法。#light(发音为hash-light)是一个编译器指令,可以简化F#的语法。
强烈建议您保持使用#light,您会发现,在大多数F#代码片段中要么会声明它,要么是假定已经声明了它。
let square x = x * x(类型推演)
这行代码定义了一个函数:square,它会求得数字x的平方。考虑一下C#中等价的代码:
public static int square(int x)
{
return x * x;
}
在C#中,您需要制定参数和返回值的类型信息,而F#则帮您搞定了。这种行为称为类型推演(Type Inference)。
从函数的签名,F#可以知道“square”函数接受一个参数“x”,并且函数返回“x * x”(在函数体内的最后一次求值将作为返回值,因此无须return关键字)。因为很多基元类型都支持*操作,比如byte,uint64,double等,F#默认会使用int类型,有符号的32位整数。
现在考虑下面的代码,它为其中的一个参数提供了“类型注解(type annotation)”,告诉编译器期望的类型。因为x标为“string”,“+”操作只定义在两个string间,因此y也必须为string类型,返回值是两个字符串拼接的结果。
> let concat (x : string) y = x + y;;
val concat : string -> string -> string
> concat "Hello, " "World!";;
val it : string = "Hello, World!"
后面我们将讨论类型推演的更多高级主题,现在您只要享受F#编译器的智能带来的方便就好了。
let numbers = [1 .. 10](F# lists)
这行代码声明了一个列表(list),其元素是从1至10。如果您用的是[|1 .. 10|],F#会创建一个.NET的整型数组(array)。而在F#中,列表是一个不可变的链表(linked list),这也是函数式编程的基础。试着将这些代码输入到FSI中(记住添加“;;”):
// Define a list
let vowels = ['e'; 'i'; 'o'; 'u']
// Attach item to front (cons)
let cons = 'a' :: vowels
// Concat two lists
let sometimes = vowels @ ['y']
我将在本系列的第二篇中更深入地介绍列表。
let squares = List.map square numbers
现在我们有了一个整型列表(numbers)和一个函数(square),我们希望创建一个新的列表,它的每一项是对numbers的每一项进行square运算后的结果。
幸运的是,List.map可以做到。考虑下面的例子:
> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
代码(fun x -> x % 2 = 0)定义了一个匿名函数,称为lamdba表达式,接受一个参数x,返回值为表达式“x % 2 = 0”的结果,也就是判断x是否为偶数。
注意我们刚才做的——将一个函数作为参数传递给另一个函数。在C#中这个并不容易。但在F#可以很清楚地表达出来,而且代码很简洁。将函数像值一样传递被称为“一等函数(first order functions)”,也是函数式编程的基础。
printfn "N^2 = %A" squares
printf是打印文本到控制台窗口的一种简单而又类型安全的方式。要更好地了解printf,考虑下面的例子,它打印一个整数、浮点数和字符串。
> printfn "%d * %f = %s" 5 0.75 ((5.0 * 0.75).ToString());;
5 * 0.750000 = 3.75
val it : unit = ()
%d,%f,%s分别是int、float、string的占位符。%A则可用于打印任何值。
Console.ReadKey(true) (.NET互操作)
我们程序的最后一行只是简单地调用了System.Console.ReadKey方法,这样可以让程序在关闭其暂停。因为F#建立在.NET的基础上,您可以在F#中调用任何.NET类库——从正则表达式到WinForms。代码“open System”用于打开命名空间,类似于C#中的using。
现在我们已经有了F#的基础知识,可以继续学习更有趣的基础类型和F#概念了,希望您关注第二篇文章!
原文链接:
http://blogs.msdn.com/chrsmith/archive/2008/05/02/f-in-20-minutes-part-i.aspx。