F#探险之旅(二):函数式编程(中) - 面向对象网 f# 学习 对象 - 面向对象技术开发

面向对象技术开发

会员投稿 投稿指南 站长资讯通告:
您的位置: 首页 > OOP语言 > F# > 正文

F#探险之旅(二):函数式编程(中)

来源: www.bianceng.cn 阅读:

操作符(Operator)

F#中,可把操作符看作一种函数调用的更为优雅的方式。操作符有两种:前缀(prefix)和中缀(infix),前者接受一个操作数(operand),出现在操作数之前;后者接受两个或多个操作数,出现在头两个操作数之间。

F#提供了丰富的操作符集,可用于数字、布尔值、字符串和集合类型。这些操作符数量甚众,限于篇幅,在此不再一一详解。本文将着重介绍如何使用和定义操作符。

类似于C#,F#的操作符也可以重载,也就是说,我们可以将不同的类型用于同一操作符,如“+”;但是与C#不同的是,各个操作数必须为相同的类型。F#的操作符重载规则与C#类似,因此任何BCL或者使用C#编写的.NET类库中的支持操作符重载的类在F#中一样支持重载。

let words = "To live " + "is " + " to function."
open System
let oneYearLater = DateTime.Now + new TimeSpan(365, 0, 0, 0, 0)

我们可以定义自己的操作符,也可以重定义已有的任何操作符(不建议这样做)。看看下面这种不好的做法:

let (+) a b = a – b
print_int (1 + 2)

看到这里,你想到了什么?是不是:这分明是在定义一个函数嘛!所以我们前面说“可把操作符看作一种函数调用的更为优雅的方式”。我们重定义了“+”操作符,所以“1 + 2”的结果为-1,这当然没什么好处,在VS中使用FSI时,怎样把“+”改回它原本的含义呢?我一般在任务管理器中把fsi进程关掉,再按回车,“+”就回来了。

自定义的操作符不能包含字母和数字,可以使用的字符如下:

!$%&+-./<=>?@^|~
:

操作符的第一个字符可以是上面第一行的任意字符,其后的字符则可以是上面的任意字符了。定义语法与函数类似,除了要将操作括起来。看下面的例子:

let (+^*) a b = (a + b) * (a * b)

结果为30。

列表(Lists)

列表是内置于F#的简单集合类型。可以是一个空表(empty list),使用方括号表示([])。我们可以将一个值与列表连接,此时要使用“::”操作符,注意要将值作为第一个操作数:

let emptyList = []
let oneItem = "one" :: []
let twoItem = "two" :: oneItem

在VS中可以看到oneItem的类型为string list。如果列表包含多个项,用上面的方法显得麻烦了,我们可以使用下面的语法:

let shortHand = ["hello "; "world!"]

[email protected]

let concatenateLists = ["one, "; "two, "] @ ["three, "; "four"]

F#要求列表中的元素类型必须是相同的,如果你确实需要列表包含不同类型的元素,那只好创建一个obj(即System.Object)类型的列表了:

let objList = [box 1; box 2.0; box "three"]

其中第三个box是可选的,这个让我想起了C#中的装箱。

F#中的列表是不可修改的,一旦创建就不能修改了。作用于列表的函数和操作符也不能修改列表,而是创建了列表的一个副本。这个特性很像C#中的string类型。看下面的例子:

#light
let printList list =
List.iter print_string list
print_newline()
let threeItems = ["one "; "two "; "three "]
let reversedList = List.rev threeItems
printList threeItems
printList reversedList

上面的iter方法接受两个参数,第一个是函数,第二个是列表,其作用是将函数依次应用于列表的每个元素,有点像C#中的foreach循环。而rev方法则返回列表的逆序列表。

打印结果为:

one tow three
three two one

上述两个方法都没有改变原来的列表。要了解关于F#列表的更多信息,建议阅读这篇文章:Mastering F# Lists。

Tags:
相关文章列表: