类型类基础 #

一、类型类概念 #

1.1 什么是类型类 #

类型类定义了一组行为,类型可以实现这些行为:

haskell
-- 类型类定义
class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool

-- a是类型参数
-- (==)和(/=)是类型类方法

1.2 类型类实例 #

haskell
-- 为类型实现类型类
instance Eq Bool where
    True  == True  = True
    False == False = True
    _     == _     = False

-- 使用
True == True   -- True
False == True  -- False

1.3 类型类约束 #

haskell
-- 类型类约束
isEqual :: Eq a => a -> a -> Bool
isEqual x y = x == y

-- 只有Eq实例的类型才能使用

二、Eq类型类 #

2.1 Eq定义 #

haskell
class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool
    
    -- 默认实现
    x /= y = not (x == y)
    x == y = not (x /= y)

2.2 实现Eq #

haskell
-- 手动实现
data Color = Red | Green | Blue

instance Eq Color where
    Red   == Red   = True
    Green == Green = True
    Blue  == Blue  = True
    _     == _     = False

-- 自动派生
data Color' = Red' | Green' | Blue'
    deriving (Eq)

2.3 使用Eq #

haskell
-- 相等比较
Red == Green  -- False
Red == Red    -- True

-- 不等比较
Red /= Green  -- True

-- elem函数
elem Red [Red, Green, Blue]  -- True

三、Ord类型类 #

3.1 Ord定义 #

haskell
class Eq a => Ord a where
    compare :: a -> a -> Ordering
    (<)  :: a -> a -> Bool
    (<=) :: a -> a -> Bool
    (>)  :: a -> a -> Bool
    (>=) :: a -> a -> Bool
    max  :: a -> a -> a
    min  :: a -> a -> a

-- Ordering类型
data Ordering = LT | EQ | GT

3.2 实现Ord #

haskell
-- 手动实现
instance Ord Color where
    compare Red Green   = LT
    compare Green Blue  = LT
    compare Red Blue    = LT
    compare x y
        | x == y    = EQ
        | otherwise = GT

-- 自动派生
data Color' = Red' | Green' | Blue'
    deriving (Eq, Ord)

3.3 使用Ord #

haskell
-- 比较
Red < Green   -- True
Blue > Green  -- True

-- 排序
sort [Blue, Red, Green]  -- [Red, Green, Blue]

-- 最大最小
max Red Green  -- Green
min Red Green  -- Red

四、Show类型类 #

4.1 Show定义 #

haskell
class Show a where
    showsPrec :: Int -> a -> ShowS
    show      :: a -> String
    showList  :: [a] -> ShowS

4.2 实现Show #

haskell
-- 手动实现
instance Show Color where
    show Red   = "Red"
    show Green = "Green"
    show Blue  = "Blue"

-- 自动派生
data Color' = Red' | Green' | Blue'
    deriving (Show)

-- 记录语法
data Person = Person
    { name :: String
    , age  :: Int
    } deriving (Show)
-- show (Person "John" 30) = "Person {name = \"John\", age = 30}"

4.3 使用Show #

haskell
-- 转字符串
show 42        -- "42"
show True      -- "True"
show [1, 2, 3] -- "[1, 2, 3]"

-- 打印
print :: Show a => a -> IO ()
print = putStrLn . show

五、Read类型类 #

5.1 Read定义 #

haskell
class Read a where
    readsPrec :: Int -> ReadS a
    readList  :: ReadS [a]

type ReadS a = String -> [(a, String)]

5.2 使用Read #

haskell
-- 从字符串读取
read "42" :: Int      -- 42
read "True" :: Bool   -- True
read "[1,2,3]" :: [Int]  -- [1, 2, 3]

-- 需要类型注解
read "42"  -- 错误!不知道类型

-- 安全读取
readMaybe :: Read a => String -> Maybe a
readMaybe s = case reads s of
    [(x, "")] -> Just x
    _         -> Nothing

5.3 自动派生 #

haskell
data Color = Red | Green | Blue
    deriving (Read)

-- 使用
read "Red" :: Color  -- Red
readMaybe "Yellow" :: Maybe Color  -- Nothing

六、Enum类型类 #

6.1 Enum定义 #

haskell
class Enum a where
    succ :: a -> a
    pred :: a -> a
    toEnum :: Int -> a
    fromEnum :: a -> Int
    enumFrom :: a -> [a]
    enumFromThen :: a -> a -> [a]
    enumFromTo :: a -> a -> [a]
    enumFromThenTo :: a -> a -> a -> [a]

6.2 实现Enum #

haskell
-- 自动派生
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
    deriving (Enum, Show)

-- 使用
succ Monday    -- Tuesday
pred Friday    -- Thursday
fromEnum Monday  -- 0
toEnum 1 :: Day  -- Tuesday

6.3 枚举范围 #

haskell
-- 枚举范围
[Monday .. Friday]  -- [Monday, Tuesday, Wednesday, Thursday, Friday]

[Monday, Wednesday .. Sunday]  -- [Monday, Wednesday, Friday, Sunday]

-- 数值枚举
[1..10]      -- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 3..10]   -- [1, 3, 5, 7, 9]
['a'..'z']   -- "abcdefghijklmnopqrstuvwxyz"

七、Bounded类型类 #

7.1 Bounded定义 #

haskell
class Bounded a where
    minBound :: a
    maxBound :: a

7.2 实现Bounded #

haskell
-- 自动派生
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
    deriving (Bounded, Enum, Show)

-- 使用
minBound :: Day  -- Monday
maxBound :: Day  -- Sunday

7.3 使用Bounded #

haskell
-- 获取范围
allDays :: [Day]
allDays = [minBound .. maxBound]
-- [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]

-- 数值范围
minBound :: Int   -- 最小Int值
maxBound :: Int   -- 最大Int值
minBound :: Char  -- '\NUL'
maxBound :: Char  -- '\1114111'

八、Num类型类 #

8.1 Num定义 #

haskell
class Num a where
    (+) :: a -> a -> a
    (-) :: a -> a -> a
    (*) :: a -> a -> a
    negate :: a -> a
    abs :: a -> a
    signum :: a -> a
    fromInteger :: Integer -> a

8.2 Num层次结构 #

haskell
-- Num是数值类型的基础
class Num a where ...

class Num a => Fractional a where
    (/) :: a -> a -> a
    recip :: a -> a
    fromRational :: Rational -> a

class Fractional a => Floating a where
    pi :: a
    exp :: a -> a
    log :: a -> a
    sin :: a -> a
    cos :: a -> a
    ...

8.3 Integral类型类 #

haskell
class (Real a, Enum a) => Integral a where
    quot :: a -> a -> a
    rem :: a -> a -> a
    div :: a -> a -> a
    mod :: a -> a -> a
    toInteger :: a -> Integer

九、类型类继承 #

9.1 继承关系 #

haskell
-- Ord继承Eq
class Eq a => Ord a where ...

-- Num继承结构
class Num a where ...
class Num a => Fractional a where ...
class Fractional a => Floating a where ...

-- Integral继承
class (Real a, Enum a) => Integral a where ...

9.2 约束传递 #

haskell
-- 约束会传递
sort :: Ord a => [a] -> [a]

-- 调用sort需要Ord实例
-- Ord需要Eq实例

十、实践示例 #

10.1 自定义类型类型类 #

haskell
-- 定义类型
data TrafficLight = Red | Yellow | Green

-- 实现Eq
instance Eq TrafficLight where
    Red == Red = True
    Yellow == Yellow = True
    Green == Green = True
    _ == _ = False

-- 实现Show
instance Show TrafficLight where
    show Red = "Red light"
    show Yellow = "Yellow light"
    show Green = "Green light"

10.2 派生多个类型类 #

haskell
-- 一次派生多个
data Status = Pending | Active | Completed | Failed
    deriving (Show, Read, Eq, Ord, Enum, Bounded)

-- 使用
show Pending        -- "Pending"
read "Active" :: Status  -- Active
Pending < Active    -- True
[Pending ..]        -- [Pending, Active, Completed, Failed]

10.3 类型类组合使用 #

haskell
-- 组合使用类型类
process :: (Show a, Ord a) => [a] -> String
process xs = show (sort xs)

-- 多重约束
analyze :: (Eq a, Show a, Ord a) => [a] -> String
analyze xs = 
    "Sorted: " ++ show (sort xs) ++ 
    ", Unique: " ++ show (nub xs)

十一、总结 #

类型类基础要点:

  1. Eq:相等比较 == /=
  2. Ord:有序比较 < > compare
  3. Show:转字符串 show
  4. Read:从字符串读取 read
  5. Enum:枚举 succ pred [a..b]
  6. Bounded:有界 minBound maxBound
  7. Num:数值运算 + - *
  8. 派生deriving 自动生成实例

掌握类型类基础后,让我们继续学习自定义类型类。

最后更新:2026-03-27