《Real World Haskell》笔记(6):使用类型类

类型类的作用
  • 若无类型类,必须为不同类型(type)实现功能类似的非重名的函数(function)以使用
  • 若用类型类,则可以提高效率。例如, 如果能用 == 对比任何类型的值,就会很方便

通过类型类可以定义通用(generic)函数,该函数能对几乎任何东西(anything)合法。对于具有比较功能的函数而言,通过写一个通用函数,能够比较所有的东西,即 generic programming :如果一段代码可以进行比较,generic code应该就能够接受任何数据类型,并且对于这些类型,编译器是知道如何比较的,如果以后新类型被添加进来,现有的代码也不应该被修改。

类型类(Typeclass) 与 实例(Instance)

类型类定义一系列函数,这些函数对于不同类型而言具有不同的函数实现。

class BasicEq a where
    isEqual :: a -> a -> Bool
    isEqual x y = not (isNotEqual x y)

    isNotEqual :: a -> a -> Bool
    isNotEqual x y = not (isEqual x y)
--isEqual :: (BasicEq a) => a -> a -> Bool
--对于所有的类型 a ,只要 a 是 BasicEq 的一个实例,isEqual 接受两个类型为 a 的参数,返回一个 Bool

instance BasicEq Bool where--定义类型类实例
    isEqual False False = True
    isEqual True  True  = True
    isEqual _     _     = False

{-类型类Eq

class  Eq a  where
 (==), (/=) :: a -> a -> Bool
    -- Minimal complete definition:
    --     (==) or (/=)
 x /= y     =  not (x == y)
 x == y     =  not (x /= y)

-}
  • 使用 class 关键字声明 typeclass ,命名为 BasicEq
  • 引用命名为 a 的 instance type ,只要实现了类型类中定义的函数,实例类型可以是任何类型
  • 在类型类的定义的第一行,引用实例类型的命名可以是任意的,需要注意的是若使用 a 来表示实例类型,那么函数签名中也必须使用 a 来代表这个实例类型
  • 为了避免让类型类的用户为所有类型都定义两个函数,可以提供两个函数的默认实现,不过每个函数取决于另一个来计算答案,因此至少一个函数要被实现,否则代码将产生死循环
重要的内置类型类
  • Show类型类用于将值转换为字符串, show :: Show a => a -> String
    show 1=="1" show "str"=="\"str\"" putStrLn "1"->1 putStrLn "\"str\""->"str"
    print 1->1 print "1"->"1"
  • Read类型类用于将字符串转换为值,read :: Read a => String -> a
    为使read函数返回正确类型的值,必须给它指定正确的类型,例如read "3"会因未指定类型导致异常,read "5.0"::Integer会因Integer解析器不能接受小数点导致异常,正确如read "3"::Double,值为3.0
序列化

把内存中的数据转化成为序列的过程

Prelude> let years = [1999, 2010, 2012]
Prelude> show years
"[1999,2010,2012]"
Prelude> writeFile "years.txt" (show years) #序列化
Prelude> input <- readFile "years.txt"
Prelude> input                  
"[1999,2010,2012]"
Prelude> (read input)::[Int] #反序列化
[1999,2010,2012]
数值类型及其对应类型类
类型 解释 Bits Bounded Floating Fractional Integral Num Real RealFrac
Double 双精度浮点数 X X X X X
Float 单精度浮点数 X X X X X
Int 固定精度带符号整数 X X X X X
Integer 任意精度带符号整数 X X X X
Rational or any Ratio 任意精度有理数 X X X X
Word 固定精度无符号整数 X X X X X
自动派生
  • Haskell可以自动将类型派生为 Read 、 Show 、 Bounded 、 Enum 、 Eq 和 Ord 的实例
  • 自动派生某个类型类的一个实例时,该类型的值构造器的构造子也必须是给定类型类的实例
--由于Book不是类型类Show的实例,BookInfo不能自动派生
data Book = Book
data BookInfo = BookInfo Book
                deriving (Show)
newtype关键字
newtype NewtypeInt = N Int
    deriving (Eq, Ord, Show)

newtype 目的是重命名一个存在着的类型,来给它一个独特的身份,声明方式与data相似。

data与newtype的区别:

  • newtype 只能有一个值构造器,并且构造器仅有一个字段,newtype的作用是限制已存在类型使用
  • data 关键字创建的类型,有一个簿记保持(book-keeping)的开销在运行时,追踪(track)某个值是由哪个值构造器创造的

type与newtype的区别:

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

推荐阅读更多精彩内容