F#与FP - 面向对象网 f# 学习 对象 - 面向对象技术开发

面向对象技术开发

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

F#与FP

来源: www.bianceng.cn 阅读:

做回你自己

每当提到内向的性格,人们就会联想到"沉默,不爱说话"、"孤僻,不善交际"、"神秘,不够open"等个性特征。就连一些知名的心理学词典也使用了消极的描述来定义内向,比如说,《心理学词典》(Dictionary of Psychology)把内向描述为"专注于自己的思想,回避社会交往,倾向于逃离现实世界",而《心理学国际词典》(The International Dictionary of Psychology)则把内向定义为"一种主要的人格特质,其特征是专注于自我,缺少社交能力,以及较为消极被动"。人们把内向的性格视为一种有问题的人格特质,而我们的社会也不断强调外向的性格才是健康发展的自然结果,无怪乎很多性格内向的人都羞于承认自己的本真,并承受着巨大的社会压力。

类似的情况也发生在函数式编程的身上。我曾经在hubFS.net看到一篇帖子,作者说某天他告诉同事自己在业余时间里做了一些函数式编程,而得到的回应却是:"Functional programming - isn't that the long haired, dope smoking end of computing?"这个描述让我联想到一个性格非常内向的人,整天把自己关在房间里做计算,不理发、不洗澡、吃喝随便,偶尔出来买点东西就像野人出山,招来无数奇怪目光。如果这就是人们对函数式程序员的印象,那么你就不必对人们说函数式编程语言是数学家的语言或者只适合在大学里做研究时使用感到奇怪了。

难道内向的性格真的一无是处吗?非也。最近在读《内向者优势》,它不但让我了解到内向的性格和外向的性格之间的差异只是由于不同的大脑机制,而且让我认识到内向的性格所具有的珍贵品性——"高度集中注意力的能力,对每个相关人员因变化而受到影响的体会,观察力,摆脱限制、思考问题的习性,作出不寻常决定的意志力,以及使外界放缓脚步的潜力"。我曾经在郑辛遥的《智慧快餐》上读到这样一句话:

做人累,大多是因为扮演了另一个自己。

或许,性格内向的人应该重新发现自身固有的价值,而不是试图把自己改造成性格外向的人。

同样地,函数式编程也应该有它自己的一片天空。Michael L. Scott在《Programming Language Pragmatics》里介绍函数式编程的概念时曾经提到"Many programmers—probably most—who have written significant amounts of software in both imperative and functional styles find the latter more aesthetically appealing"。这段时间,由于F#的学习,我也如饥似渴地阅读着各种介绍函数式编程的文章,有时候我不禁在想:我们是否对函数式编程有太多先入为主的偏见,以至于我们无法更深入、更完整地了解它呢?如果是的话,那就太可惜了,因为我们否定函数式编程的同时也会错过那些本应得到重视的价值。或许,我们应该尝试了解函数式编程在哪些方面能有更出色的表现,而不是一味地排斥它。

今天的主角——函数

在我印象里,map函数通常用来把一组元素按照一定的规则映射成另一组元素,例如,下面的代码把一个整数列表映射成由对应元素的平方组成的列表:

\

图 1

有一次,我在《Programming Language Pragmatics》介绍高阶函数(10.5 Higher-Order Functions)的那节里看到map函数的一个"新玩法":

\

图 2

箭头左边是这个map函数在Scheme里的用法,而箭头右边则是输出结果。这次,它接受两个输入列表,映射规则是一个二元函数,将会应用到这两个列表里位置对应的两个元素,而运算结果将会放在输出列表的对应位置上。想想看,如果让你来实现这个map函数,编程语言不限,你会怎么做?(嘿,我建议你先想一下如何在你喜欢的语言里实现这个map函数,然后再继续读下去。)

那天晚上,我躺在床上睡不着,突然来劲,就起来写下这段代码:

\

代码 1

这是什么?函数吗?哪些是参数?类型是什么?返回值呢?函数体怎么看?……冷静点!且听我慢慢道来。

首先,map确实是一个函数,而且是一个高阶函数,你可能已在别的地方听过这个术语了,所谓的高阶函数就是指至少满足下列一个条件的函数:(1)接受一个或多个函数作为输入;(2)输出一个函数。读到这里,你可能会感到疑惑:"map函数什么时候接受函数作为输入啦?"没看出来是吧?仔细观察代码1,是不是充满了"类型不明"的符号?当你试图从头到尾阅读这段代码时,有没有头晕、胸闷、呼吸急速、手腕无力等感觉?如果有,那么你很可能患了"显式类型声明依赖综合症"。哈哈,开个玩笑而已。

接着,把map函数的签名和图2里的代码做一个匹配,不难看出,f、l和r就是map函数的参数,其中,f是用于表示映射规则的二元函数,l和r则是两个参与运算的输入列表,然而,f、l和r具体又是什么类型呢?或许,你曾听说,F#的一大亮点就是它的类型推断系统,现在正是考验这个系统的最佳时机,看看它会把f、l和r三个参数以及函数的返回值推断成什么类型。在F# Interactive里输入map函数的代码,你将会看到如下输出:

\

图 3

Tags:
相关文章列表: