第四节 函数的语法.pdf

  1. 1、本文档共5页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第四章 函数的语法 模式匹配 注意,门卫! Where? Let it be case表达式 模式匹配 本章讲的就是haskell那套酷酷的语法结构,先从模式匹配开始。模式匹配通过 查数 据的特定结构来 查其是否匹配,并按模式从中取得数据。 在定义函数时,你可以为不同的模式分别定义函数体,这就让代码更加简洁易读。你 可以匹配⼀切数据类型数字,字符,List ,元组,等等。我们弄个简单函数,让它 查我们传给它的数字是不是7 。 lucky :: (Integral a) = a - String lucky 7 = LUCKY NUMB R S V N! lucky x = Sorry, youre out of luck, pal! 在调⽤lucky时,模式会从上⾄下进⾏ 查,⼀旦有匹配,那对应的函数体就被应⽤ 了。这个模式中的唯⼀匹配是参数为7 ,如果不是7 ,就转到下⼀个模式,它匹配⼀切 数值并将其绑定为x 。这个函数完全可以使⽤if实现,不过我们若要个分辨1到5 中的数 字,⽽⽆视其它数的函数该怎么办?要是没有模式匹配的话,那可得好⼤⼀棵if-else 树了 ! sayMe :: (Integral a) = a - String sayMe 1 = One! sayMe 2 = Two! sayMe 3 = Three! sayMe 4 = Four! sayMe 5 = Five! sayMe x = Not between 1 and 5 注意下,如果我们把最后匹配⼀切的那个模式挪到最前,它的结果就全都是Not between 1 and 5 了。因为它⾃⼰匹配了⼀切数字,不给后⾯的模式留机会。 记得前⾯实现的那个阶乘函数么?当时是把n的阶乘定义成了product [1..n]。也 可以写出像数学那样的递归实现,先说明0 的阶乘是1,再说明每个正整数的阶乘都是 这个数与它前驱(predecessor)对应的阶乘的积。如下便是翻译到haskell的样⼦: factorial :: (Integral a) = a - a factorial 0 = 1 factorial n = n * factorial (n - 1) 这就是我们定义的第⼀个递归函数。递归在haskell 中⼗分重要,我们会在后⾯深⼊理 解。如果拿⼀个数 (如3 )调⽤factorial函数,这就是接下来的计算步骤:先计算 3*factorial 2,factorial 2等于2*factorial 1,也就是3*(2* (factorial 1))。factorial 1等于1*factorial 0,好,得3*(2* (1*factorial 0)),递归在这⾥到头了,嗯我们在万能匹配前⾯有定义,0 的阶 乘是1.于是最终的结果等于3*(2*(1*1))。若是把第⼆个模式放在前⾯,它就会捕获 包括0在内的⼀切数字,这⼀来我们的计算就永远都不会停⽌了。这便是为什么说模 式的顺序是如此重要:它总是优先匹配最符合的那个,最后才是那个万能的。 模式匹配也会失败。假如这个函数: charName :: Char - String charName a = Albert charName b = Broseph charName c = Cecil 拿个它没有考虑到的字符去调⽤它,你就会看到这个: ghci charName a Albert ghci charName b Broseph ghci charName h *** xception: tut.hs:(53,0)-(55,21): Non-exhaustive patterns in 它告诉我们说,这个模式不够全⾯。因此,在定义模式时,⼀定要留⼀个万能匹配的 模式,这样我们的程序就不会为了不可预料的输⼊⽽崩溃了。 对T ple 同样可以使⽤模式匹配。写个函数,将⼆维空间中的向量相加该如何?将它们 的x项和y项分别相加就是了。如果不了解模式匹配,我们很可能会写出这样的代码: addVectors :: (Num a) = (a, a) - (a, a) - (a, a) addVectors a b = (fst a + fst b, snd a + snd b) 嗯,可以运⾏。但有更好的

文档评论(0)

kehan123 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档