重载与类型分类 overloading and type classes
DESCRIPTION
重载与类型分类 Overloading and Type Classes. 什么是重载? 类型分类的概念 签名与特例. 重载. 运算符 (+) 可以用于计算两个相同类型数值之和: > 1 + 2 3 > 1.2 + 1.1 3.3 我们称运算符 (+) 被 重载 : (+) 可用于不同的类型,但是,它在不同类型上的定义不同。. 为什么使用重载. 假设我们要定义一个函数检查一个元素是否出现在一个布尔值列表中: elemBool :: Bool -> [Bool] -> Bool elemBool x [] = False - PowerPoint PPT PresentationTRANSCRIPT
重载与类型分类Overloading and Type Classes
• 什么是重载?• 类型分类的概念• 签名与特例
重载
运算符 (+) 可以用于计算两个相同类型数值之和:
> 1 + 2
3
> 1.2 + 1.1
3.3
我们称运算符 (+) 被重载: (+) 可用于不同的类型,但是,它在不同类型上的定义不同。
为什么使用重载 假设我们要定义一个函数检查一个元素是否出现在一个布尔值列表中: elemBool :: Bool -> [Bool] -> Bool
elemBool x [] = False
elemBool x (y:ys) = (x == y || elemBool x ys)
如果我们想定义一个函数检查一个元素是否出现在一个整数列表中: elemInt :: Int -> [Int] -> Bool
在这里重复上述定义,只是将布尔类型上的相等运算替换为整数类型上的相等即可。
Bool 上的相等
为什么使用重载
在这种情况下,我们希望定义一个下列类型的函数: elem :: a -> [a] -> Bool
elem x [] = False
elem x (y:ys) = (x == y || elem x ys)
条件是类型 a 上定义了相等运算 (==) 。
Haskell 使用类型分类系统实现上述需求。
类型分类 Classes
一个类型分类或者类 (class )是支持某些重载运算的类型的集合,这些运算又称为类的方法。
例如,定义了相等运算和不相等运算的类型的集合称为 Eq( 相等类 ),两个运算记作 (==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
Eq 类的定义是:
class Eq a where
(==) :: a - > a -> Bool
(/=) :: a -> a -> Bool
定义类
class Visible a where
toString :: a -> String
size :: a -> Int
类名
签名:运算名及其类型
特例
一个类的成员称为一个特例。 Eq的特例包括基本类型 Int, Float, Bool, Char.
将一个类型定义为一个类的特例的方法是:通过使用 instance 特例说明语句并定义类的方法。例如,说明 Bool 是 Eq 的特例: instance Eq Bool where
True == True = True
False == False = True
_ == _ = False
x /= y = not (x == y)
例
定义 Bool 是 Visible 的特例: instance Visible Bool where
toString True = “True”
toString False = “False”
size _ = 1
函数 elem
返回函数 elem 的例子,我们希望其类型是: elem :: a -> [a] -> Bool
其中类型 a上定义了相等,或者说类型 a是类 Eq 的特例。这样的要求可以在 Haskell 中如下说明:
elem :: Eq a => a -> [a] -> Bool
函数的定义保持不变: elem x [] = False elem x (y:ys) = (x == y || elem x ys)
一个带有约束的类型称为重载类型,具有重载类型的函数称为重载函数。
约束
缺省定一
一个类的方法可以有缺省定义,缺省定义可以被特例定义覆盖。 例如, Eq 类定义如下: class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y) 缺省定义
子类
一个类可能依赖于另一个类。例如,类 Ord 包含那些可以比较其值的类型。一个属于类 Ord 的类型不仅支持相等运算,而且支持比较运算 >, >= 等。为此,定义 class Eq a => Ord a where
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
compare :: a -> a -> Ordering
Ord 是 Eq的子类
多重约束
在定义特例或者函数时可能需要多重约束。例如, instance (Eq a, Eq b) => Eq (a, b) where
(x, y) == (u, v) = x == u && y == v
instance (Visible a, Visible b) => Visible (a, b) where
toString (x, y) = “(“++toString x ++ “,” ++ toString y ++ “)”
size (x, y) = size x + size y
基本类
Equality: Eq
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y)
所有的基本类型都是 Eq 类的特例。列表类型,多元组类型都是 Eq类的特例,只要其基类或者分量类型是 Eq的特例。
可显示类
可显示类 Show 包含其值可以显示成串的类型: class Show a where
show :: a -> String
函数 show 将类型 a的值显示成串。例如,
instance Show Bool where
show True = “True”
show False = “False”
可读类
类 Read 包含其值可以由串转换来的类型,它的方法是: read :: String -> a
所有的基本类型、列表类型和多元组类型都是类Read 的特例,只要列表的基类或者多元组的分量类型属于类 Read 。 > read “False” :: Bool
False
> read “(‘a’, False)” :: (Char, Bool)
(‘a’, False)
有序类
有序类 Ord
class (Eq a) => Ord a where
compare :: a -> a -> Ordering
(<), (<=), (>=), (>) :: a -> a -> Bool
min, max :: a -> a -> a
其中类型 Ordering 包含三个元素 LT, EQ 和 GT , 分别表示比较两个值的三个可能结果。
缺省定义: compare x y
| x == y = EQ
| x <=y = LT
| otherwise = GT
x <= y = compare x y /= GT
max x y | x >= y = x
| otherwise = y
Num – 数值类
数值类 Num 包含其元素可以比较相等,可以显示并且支持下列数值元算的类型: (+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
negate :: a -> a
abs :: a ->
signum :: a -> a
基本类型 Int, Integer 和 Float 是 Num 的特例 .
多态函数与重载
函数 length 可以计算任意类型上列表的长度:
length :: [a] -> Int
多态函数在所有类型上的定义是一致的。
而重载则不然,例如 elem :: Eq a => a -> [a] -> Bool
其定义依赖于不同的类型。
length [] = 0 length (x:xs) = 1 + length xs
elem x [] = False elem x (y:ys) = (x == y||elem x ys)