Haskell入门(五)(续)高阶函数(higher-order functions)

参考教材:Learn You a Haskell for Great Good (http://learnyouahaskell.com/)

操作环境:Ubuntu下Linux64位虚拟机

python入门编程, 之后用c++学习数据结构,Haskell萌新。

由于对Haskell中一些词语的中文翻译并不了解,接下来的内容中重点名词将有英文和我理解的中文。


Chapter5主要内容(续)

匿名函数(Lambdas)

lambdas基础知识

lambdas是仅供单次使用的匿名函数。在写法上它比普通的函数更简单。在高阶函数的实现中有时会遇到它。适当使用lambdas函数可以增强代码的可读性。

匿名函数,顾名思义,就是函数没有名称。Haskell语言里的lambdas以\开头,后面跟参数,再接以->开头的函数体。

比较匿名函数和普通的函数,我们发现它们的结构类似,只是匿名函数中不需要进行函数声明和函数名称,以->符号替代了普通函数中的=。匿名函数同样支持样式匹配(pattern matching),区别是我们针对一个参数只能使用一次样式匹配。如果匹配失败且得不到解决,程序会报错终止。

lambdas示例


lambdas示例

这里是几个Lambdas函数的使用。右侧两个numLongChains函数放在一起作为对比,在Load文件时,第三个函数尚不存在。

列表折叠函数(fold)

列表折叠函数可用于实现按元素递归列表的操作。它需要三个参数的输入:二元函数,起始值,待折叠列表。从起始值开始,按照折叠顺序,依次将当前值与待折叠列表中的元素进行二元操作,直到列表遍历完毕。我们可以通过调用不同的函数来控制折叠的方式。

左折叠(fold left)

左折叠的实现

右折叠(fold right)

与左折叠原理类似,区别是从待折叠列表的右侧开始操作。这可能造成折叠函数的写法上与左折叠有区别:用于累计的accumulator写在右边。

右折叠的实现

在这里使用右折叠,而不使用左折叠的理由是,左折叠用到的++函数需要遍历元素,而右折叠用到的:函数只需要O(1)的复杂度。在列表规模较大时,右折叠有优势。

右折叠的另一个优势是,借助于Haskell laziness的特性,它可以针对一些无穷列表进行处理。这部分的具体内容建议参考Stack Overflow :foldl versus foldr behavior with infinite lists.下面是截图。

Stack Overflow上关于两种fold的区别的部分解释

折叠的一些例子


折叠的一些例子

相似:扫描函数(scan)

scan函数可以用来监控折叠的过程。同折叠一样,它也有scanl和scanr两种形式,要求二元函数操作,初始值,待扫面列表。区别是,它还会保留所有中间变量。具体例子如图:

扫描函数示例

除了上面提到的函数外,还有不需要初始值(默认为首个)foldl1, foldr1, scanl1, scanr1函数。这里暂时不详细介绍。

右结合(right-associative)函数操作符$

通常情况下,使用空格分隔实现的函数是左结合的,它们的优先级极高。下面要讲的函数操作符$却是右结合的,它有最低的优先级。代码中的$表明,这个符号右边的内容会先处理,处理完毕后作为参数传递给左边的函数。

这一符号的第一个作用是,利用它的右结合特性,减少代码中括号的出现,增强代码的可读性。

此外,这一符号还可以起到调用函数应用的作用(lets us treat function application like just another function)。可能在想法上有点类似于函数指针?

$操作符的两个作用

函数复合(function composition)

在Haskell里,我们使用.来实现函数复合。需要注意,f.g要求f的返回值和g的参数值有相同的类型。

由于函数复合符号.是右结合的,我们可以按照需要复合多个函数。

函数复合示例

如果我们希望处理的函数需要多个参数呢?我们可以运用前面的不完全函数来实现。

综合上面我们讲到的,如果我们想要处理简化一个多个括号的函数,我们可以从最内层开始写,在需要的地方使用$符号减少括号,使用不完全函数处理函数间的复合调用。

函数复合也可以在无点号(point-free)的情况下实现,具体参考前面函数部分的例子,在此不再赘述。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容