- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第⼋章 构造我们⾃⼰的类型和类型类
数据类型⼊门
Record Syntax
类型参数
派⽣实例
类型别名
数据类型⼊门
在前⾯的章节中,我们谈了⼀些Haskell 内置的类型和类型类。 在本章,我们将学习
构造类型和类型类的⽅法。
我们以已经见识了许多数据类型,如Bool、Int、Char、Maybe等等,不过该怎样
构造⾃⼰的数据类型呢?好问题,使⽤data关键字是⼀种⽅法。我们看看Bool在标准
库中的定义:
data Bool = False | True
data表⽰我们要定义⼀个新的数据类型。=的左端标明类型的名称即Bool,=的右端
就是值构造⼦ (Value Constructor ),它们明确了该类型可能的值。|读作“或” ,所以
可以这样阅读该声明:Bool类型的值可以是True或False 。类型名和值构造⼦的⾸字
母必⼤写。
相似,我们可以假想Int类型的声明:
data Int = -2147483648 | -2147483647 | ... | -1 | | 1 | 2 | ... |
⾸位两个值构造⼦分别表⽰了Int类型可能的最⼩值和最⼤值,这些省略号表⽰我们省
去了中间⼤段的数字。当然,真实的声明不是这个样⼦的,这样写只是为了便于理
解。
我们想想Haskell 中图形的表⽰⽅法。表⽰圆可以⽤⼀个元组,如
(43.1,55. ,1 .4),前两项表⽰圆⼼的位置,末项表⽰半径。听着不错,不过三
维向量或其它什么东西也可能是这种形式 !更好的⽅法就是⾃⼰构造⼀个表⽰图形的
类型。假定图形可以是圆 (Circle )或长⽅形 (Rectangle ):
data Shape = Circle Float Float Float | Rectangle Float Float Floa
这是啥,想想?Circle的值构造⼦有三个项,都是Float 。可见我们在定义值构造⼦
时,可以在后⾯跟⼏个类型表⽰它包含值的类型。在这⾥,前两项表⽰圆⼼的坐标,
尾项表⽰半径。Rectangle的值构造⼦取四个Float项,前两项表⽰其左上⾓的坐
标,后两项表⽰右下⾓的坐标。
谈到“项”(field) ,其实应为“参数”(para eters) 。值构造⼦的本质是个函数,可以返回⼀
个类型的值。我们看下这两个值构造⼦的类型声明:
ghci :t Circle
Circle :: Float - Float - Float - Shape
ghci :t Rectangle
Rectangle :: Float - Float - Float - Float - Shape
Cool ,这么说值构造⼦就跟普通函数并⽆⼆致咯,谁想得到?我们写个函数计算图形
⾯积:
surface :: Shape - Float
surface (Circle _ _ r) = pi * r ^ 2
surface (Rectangle x1 y1 x2 y2) = (abs $ x2 - x1) * (abs $ y2 - y1
值得⼀提的是,它的类型声明表⽰了该函数取⼀个Shape值并返回⼀个Float值。写
Circle - Float是不可以的,因为Circle并⾮类型,真正的类型应该是Shape 。这
与不能写True-False的道理是⼀样的。再就是,我们使⽤的模式匹配针对的都是
值构造⼦。之前我们匹配过[]、False或5,它们都是不包含参数的值构造⼦。
我们只关⼼圆的半径,因此不需理会表⽰坐标的前两项:
ghci surface $ Circle 1 2 1
314 .15927
ghci surface $ Rectangle 1 1
1 .
Yay ,it works !不过我们若尝试输出Circle 1 2 到控制台,就会得到⼀个错误。
这是因为Haskell还不知道该类型的字符串表⽰⽅法。想想,当我们往控制台输出值的
时候,Haskell会先调⽤show函数得到这个值的字符串表⽰才会输出。因此要让我们的
Shape类型成为Show类型类的成员。可以这样修改:
data Shape = Circle Float Float Float | Rectangle Float Float Floa
先不去深究deriving (派⽣),可以先这样理解:若在data声明的后⾯加上d
原创力文档


文档评论(0)