收藏 分享(赏)

5.HigherOrderFunctions.ppt

上传人:kpmy5893 文档编号:8408510 上传时间:2019-06-25 格式:PPT 页数:40 大小:166KB
下载 相关 举报
5.HigherOrderFunctions.ppt_第1页
第1页 / 共40页
5.HigherOrderFunctions.ppt_第2页
第2页 / 共40页
5.HigherOrderFunctions.ppt_第3页
第3页 / 共40页
5.HigherOrderFunctions.ppt_第4页
第4页 / 共40页
5.HigherOrderFunctions.ppt_第5页
第5页 / 共40页
点击查看更多>>
资源描述

1、高阶函数 Higher Order Functions,阅读第九章、第十章,计算模式的推广,我们经常需要对列表的元素进行某种统一的操作:doubleAll : Int - IntdoubleAll = doubleAll (x:xs) = 2*x : doubleAll xs 或者doubleAll xs = 2*x | x- xs,又如:isEven xs = even x | x - xs,even : Int - Bool even n = nmod 2 = 0,高阶函数,一般的计算模式:x, y, z, f x, f y, f z, ,我们把这种模式称作映射map:map f xs =

2、 f x | x - xs map的第一个参数是函数,这种以函数为输入 的函数称为高阶函数(higher order functions)。,map的另一种定义方法 map f = . map f (x:xs) = f x : map f xs,例如 map double 1,2,3,4,5 = 2,4,6,8,10 map even 1, 2, 3, 4, 5 = False, True, False, True, False,使用高阶函数可以书写更简洁的函数定义:doubleAll xs = map double xsisEven xs = map even xs,map的类型是什么?,m

3、ap even 1, 2, 3, 4, 5 = False, True, False, True, False,任意一元函数,任何a上的列表,结果是b上的列表,map的类型是多态的 map : (a - b) - a - b,map double 1,2,3,4,5 = 2,4,6,8,10,map : (Int - Bool) - Int - Bool,map : (Int - Int) - Int - Int,使用map定义水平翻转,flipH,” # ”,” # ”,”#”,” # ”,” # ”,” # ”,” # ”,”#”,” # ”,” # ”,flipH : Picture -

4、 Picture flipH pic = reverse line | line - pic,filpH pic = map reverse pic,过滤函数,例如,选出列表中的偶数:x | x- 15, even x = 2,4 又如,选取一个串中的数字x | x - “born on 15 April 1986”, isDigit x = “151986”,一般地,我们定义如下过滤模式filter p xs = x | x - xs, p x,isDigit : Char - Bool,Filter的类型是什么?,filter even 1, 2, 3, 4, 5 = 2, 4even :

5、 Int - Bool filter : (Int - Bool) - Int - Intfilter : (a - Bool) - a - a,一个表示性质的函数类型,为什么使用高阶函数?,高阶函数是函数程序设计的灵魂。许多相似的函数都可以使用一个高阶函数代替。高阶函数比一阶函数更具有表现力,我们可以通过使用不同的函数参数解决不同的问题。每当多个函数具有相似的模式时,定义一个高阶函数。,折叠的例子,sum = 0 sum (x:xs) = x + sum xs,计算模式:使用同一个运算将列表的元素结合起来。 具体到sum: 起始值0, 运算 +and: 起始值True, 运算 &,and =

6、 True and (x:xs) = x & (and xs),sum 2,4,6 = 12,and True, False, True = False,折叠函数,sum = 0 sum (x:xs) = x + sum xs,将0和+分别用参数代替, 定义一个高阶函数:,foldr op z = z foldr op z (x:xs) = x op foldr op z xs,sum xs = foldr plus 0 xswhere plus x y = x+y,sum xs = foldr plus 0 xswhere plus x y = x+y,sum xs = foldr (+)

7、0 xs,使用foldr定义的sum,或者,使用foldr的函数定义,将列表元素使用某种运算结合起来是一种常见运算,这种运算均可以使用foldr定义,而不必使用递归。,product xs = foldr (*) 1 xs concat xs = foldr (+) xs maximum (x:xs) = foldr max x xs,函数foldr的另一种解读,foldr op z = z foldr op z (x:xs) = x op foldr op z xs,例如 foldr op z (a:(b:(c:) = a op foldr op z (b:(c:)= a op (b op

8、foldr op z (c:)= a op (b op (c op foldr op z )= a op (b op (c op z) 运算 “:” 被 op代替, 被 z代替.,问题,解释下列表达式的语义 foldr (:) xs,foldr (:) xs = xs,问题,解释 foldr (:) ys xs,foldr (:) ys a,b,c = foldr (:) ys (a:(b:(c:)= (a:(b: (c: ys) = a,b,c + ys,xs+ys = foldr (:) ys xs,问题,解释 foldr snoc xs where snoc y ys = ys+y,fo

9、ldr snoc (a:(b:(c:)= a snoc (b snoc (c snoc )= ( + c) + b + a 结果是xs的逆!,reverse xs = foldr snoc xswhere snoc y ys = ys+y,表达式,表达式是函数的一种表示方法。 例如double x = 2*x 函数double可以表示为double = x. 2*x,在Haskell中表示为double = x - 2*x,当输入参数是x时,函数的结果是2*x,例 max x y = if (x if (x if (xy) then y lese x,一般地,下列定义等价:f x y z =

10、e f = x y z - e,使用表达式定义函数,reverse xs = foldr snoc xswhere snoc y ys = ys+y,可以直接使用lambda表达式代替只出现一次的函数,reverse xs = foldr (y ys - ys+y) xs,定义函数unlines,unlines “abc”, “def”, “ghi” = “abcndefnghin”unlines xs,ys,zs = xs + “n” + (ys + “n” + (zs + “n” + ),unlines xss = foldr (xs ys - xs+“n”+ys) xss,等价于 unl

11、ines xss = foldr join xsswhere join xs ys = xs + “n” + ys,又一个计算模式,在一个串中取出一个单词:takeWord “Hello, world!” = “Hello”,takeWord = takeWord (x:xs) | x/= & x/=, = x:takeWord xs| otherwise = ,模式: 当某个条件不成立时取得列表元素,直至条件为True。,推广 takeWord,takeWhile p = takeWhile p (x:xs) | p x = x:takeWhile p xs| otherwise = ,新定

12、义 takeWord xs = takeWhile (x - elem x “ ,.;”) xs,takeWord = takeWord (x:xs) | notSpace x = x:takeWord xs| otherwise = where notSpace x = elem x “ ,;.”,函数的表示法: Sections,一个二元运算只带有一个参数时表示一个函数,称为部分运算(sections):(+1) : Int - Int(1+) : Int - Int map (+1) 1,2,3 = 2,3,4 filter (0) 1,-2,3 = -2 takeWhile (0) 1

13、,-2,3 = 1,3,(a) b = ab (a) b = ba,部分应用,Haskell 允许如下定义 sum = foldr (+) 0,foldr 只带有三个参数中的 两个。,sum xs = foldr (+) 0 xs,sum = foldr (+) 0,计算 sum 1,2,3 = replacing sum by its definitionfoldr (+) 0 1,2,3 = by the behaviour of foldr1 + (2 + (3 + 0) = 6,foldr 有三个参数,部分应用,任何函数都可以应用于部分输入参数,结果是剩余参数的函数: 如果 f :In

14、t - Bool - Int - Bool 则 f 3 : Bool - Int - Boolf 3 True : Int - Boolf 3 True 4 : Bool,一个函数得到一个输入后成为等待其他输入的函数,函数应用和类型的括号结合方法,函数应用是左结合的,函数类型是右结合的: 例如 f :Int - (Bool - (Int - Bool) 或者 f : Int - Bool - Int - Bool 则 f 3 : Bool - (Int - Bool)(f 3) True : Int - Bool(f 3) True) 4 : Bool,使用高阶函数,将问题分解成一系列能够使用

15、高阶函数编程的步骤;逐渐将输入转换为期望的输出;将这些转换函数组合起来。,例:计算词数,输入:一个由许多词构成、表示文本的串。 例如“hello clouds n hello sky” 输出:一个文本中出现的所有词及其出现次数的列表,单词按照字典序排列。如“clouds: 1nhello: 2nsky: 1”,clouds: 1 hello: 2 sky: 1,第一步:将输入分解成词的列表,“hello clouds n hello sky”,“hello”, “clouds”, “hello”, “sky”,words,第二步:排序,“clouds”, “hello”, “hello”, “

16、sky”,sort,“hello”, “clouds”, “hello”, “sky”,第三步:将相同的词并入一组,“clouds”, “hello”, “hello”, “sky”,group,“clouds”, “hello”, “hello”, “sky”,第四步:计算每组词数,(“clouds”,1), (“hello”, 2), (“sky”,1),map (ws - (head ws, length ws),“clouds”, “hello”, “hello”, “sky”,第五步:格式化每一组,“clouds: 1”, “hello: 2”, “sky: 1”,map (w,n)

17、 - w+show n),(“clouds”,1), (“hello”, 2), (“sky”,1),第六步:将列表格式化,“clouds: 1nhello: 2nsky: 1n”,unlines,“clouds: 1”, “hello: 2”, “sky: 1”,clouds: 1 hello: 2 sky: 1,完整的程序,countWords : String - String countWords =unlines .map (w,n) - w+show n) .map (ws - (head ws, length ws) .groupBy (=) .sort .words,函数 gr

18、oupBy,group = groupBy (=) groupBy : (a - a - Bool) - a - a groupBy p xs - 将xs分解成 段的列表x1,x2, 其中每一段上的所有元素均满足某个性质,小结,高阶函数是计算模式的抽象。高阶函数的参数是函数。高阶函数使得许多函数的更简洁、灵活,而且大大减少了编程工作量。表达式、部分运算和部分应用可用于表示函数,作为参数时无需另行定义。Haskell提供了许多高阶函数。解决问题的一般步骤:将问题分解成能够用现有函数解决的问题,然后将这些函数粘合起来。,习题:9.9, 9.10, 9.14, 9.16, 10.4, 10.7, 10.9,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报