自定义类型类 #
一、定义类型类 #
1.1 基本语法 #
haskell
-- 使用class定义类型类
class ClassName a where
methodName :: TypeSignature
methodName = defaultImplementation -- 可选默认实现
1.2 简单示例 #
haskell
-- 定义一个可描述的类型类
class Describable a where
describe :: a -> String
-- 实现实例
instance Describable Bool where
describe True = "True: yes"
describe False = "False: no"
instance Describable Int where
describe n = "Int: " ++ show n
-- 使用
describe True -- "True: yes"
describe 42 -- "Int: 42"
1.3 多方法类型类 #
haskell
-- 多个方法的类型类
class Serializable a where
serialize :: a -> String
deserialize :: String -> a
-- 实现实例
instance Serializable Bool where
serialize True = "true"
serialize False = "false"
deserialize "true" = True
deserialize "false" = False
deserialize _ = error "Invalid boolean"
二、默认实现 #
2.1 提供默认实现 #
haskell
-- 默认实现
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
-- 默认实现
x == y = not (x /= y)
x /= y = not (x == y)
-- 实现时只需实现一个
instance Eq Bool where
True == True = True
False == False = True
_ == _ = False
-- (/=) 使用默认实现
2.2 相互依赖的默认实现 #
haskell
-- 相互依赖
class Comparable a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(>) :: a -> a -> Bool
-- 默认实现
x < y = compare x y == LT
x > y = compare x y == GT
-- 只需实现compare
instance Comparable Int where
compare x y
| x < y = LT
| x > y = GT
| otherwise = EQ
三、类型类继承 #
3.1 基本继承 #
haskell
-- 类型类继承
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
-- ...
-- Ord继承Eq
-- 实现Ord必须先实现Eq
3.2 多重继承 #
haskell
-- 多重继承
class (Show a, Eq a) => PrintableEq a where
printEq :: a -> a -> String
printEq x y =
if x == y
then show x ++ " equals " ++ show y
else show x ++ " not equals " ++ show y
-- 实现PrintableEq需要先实现Show和Eq
instance PrintableEq Int -- 使用派生
3.3 继承层次 #
haskell
-- 层次结构
class Eq a where ...
class Eq a => Ord a where ...
class Ord a => Enum a where ...
-- 实现Enum需要先实现Ord和Eq
四、参数化类型类 #
4.1 单参数类型类 #
haskell
-- 单参数
class Functor f where
fmap :: (a -> b) -> f a -> f b
-- 实现Functor
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just x) = Just (f x)
instance Functor [] where
fmap = map
4.2 多参数类型类 #
haskell
{-# LANGUAGE MultiParamTypeClasses #-}
-- 多参数类型类
class Convert a b where
convert :: a -> b
-- 实现
instance Convert Int Double where
convert = fromIntegral
instance Convert String Int where
convert = read
-- 使用
convert (42 :: Int) :: Double -- 42.0
4.3 类型依赖 #
haskell
{-# LANGUAGE FunctionalDependencies #-}
-- 类型依赖
class Collection c e | c -> e where
empty :: c
insert :: e -> c -> c
member :: e -> c -> Bool
-- c -> e 表示c决定e
-- 例如:Set Int 决定元素类型是 Int
五、实践示例 #
5.1 大小类型类 #
haskell
-- 定义大小类型类
class Sizeable a where
size :: a -> Int
isEmpty :: a -> Bool
isEmpty x = size x == 0
-- 实现实例
instance Sizeable [a] where
size = length
instance Sizeable (Maybe a) where
size Nothing = 0
size (Just _) = 1
instance Sizeable (Either a b) where
size (Left _) = 1
size (Right _) = 1
5.2 验证类型类 #
haskell
-- 验证类型类
class Validatable a where
validate :: a -> Maybe String -- Nothing表示有效
-- 用户数据
data User = User
{ userName :: String
, userAge :: Int
}
instance Validatable User where
validate (User name age)
| null name = Just "Name cannot be empty"
| age < 0 = Just "Age cannot be negative"
| age > 150 = Just "Age is too high"
| otherwise = Nothing
5.3 编码类型类 #
haskell
-- 编码类型类
class Encodable a where
encode :: a -> String
decode :: String -> Maybe a
-- 实现Bool编码
instance Encodable Bool where
encode True = "1"
encode False = "0"
decode "1" = Just True
decode "0" = Just False
decode _ = Nothing
-- 实现Int编码
instance Encodable Int where
encode = show
decode s = case reads s of
[(n, "")] -> Just n
_ -> Nothing
5.4 数学类型类 #
haskell
-- 向量类型类
class Vector v where
zero :: v
add :: v -> v -> v
scale :: Double -> v -> v
dot :: v -> v -> Double
-- 二维向量
data Vec2 = Vec2 Double Double
instance Vector Vec2 where
zero = Vec2 0 0
add (Vec2 x1 y1) (Vec2 x2 y2) = Vec2 (x1 + x2) (y1 + y2)
scale s (Vec2 x y) = Vec2 (s * x) (s * y)
dot (Vec2 x1 y1) (Vec2 x2 y2) = x1 * x2 + y1 * y2
六、高级特性 #
6.1 关联类型 #
haskell
{-# LANGUAGE TypeFamilies #-}
-- 关联类型
class Container c where
type Element c
empty :: c
insert :: Element c -> c -> c
getElements :: c -> [Element c]
-- 实现
instance Container [a] where
type Element [a] = a
empty = []
insert = (:)
getElements = id
instance Container (Maybe a) where
type Element (Maybe a) = a
empty = Nothing
insert x _ = Just x
getElements Nothing = []
getElements (Just x) = [x]
6.2 关联数据类型 #
haskell
{-# LANGUAGE TypeFamilies #-}
-- 关联数据类型
class Expression e where
data Value e
evaluate :: e -> Value e
-- 实现
instance Expression Int where
data Value Int = IntValue Int
evaluate = IntValue
instance Expression Bool where
data Value Bool = BoolValue Bool
evaluate = BoolValue
6.3 最小完整定义 #
haskell
-- 指定最小实现
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
{-# MINIMAL (==) | (/=) #-}
-- 只需实现其中一个
七、类型类最佳实践 #
7.1 命名约定 #
haskell
-- 类型类名:大写开头,形容词或名词
class Serializable a where ...
class Comparable a where ...
class Container a where ...
-- 方法名:小写开头,动词
class Serializable a where
serialize :: a -> String
deserialize :: String -> Maybe a
7.2 设计原则 #
haskell
-- 好:单一职责
class Show a where
show :: a -> String
-- 不好:太多不相关方法
class BadClass a where
show :: a -> String
eq :: a -> a -> Bool
add :: a -> a -> a
7.3 提供默认实现 #
haskell
-- 好:提供合理的默认实现
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x /= y = not (x == y) -- 默认实现
八、总结 #
自定义类型类要点:
- class定义:
class ClassName a where ... - instance实现:
instance ClassName Type where ... - 默认实现:提供方法默认实现
- 继承:
class Super a => Sub a where ... - 多参数:
class Class a b where ... - 关联类型:
type Element c - 最佳实践:单一职责、合理命名、提供默认
掌握自定义类型类后,让我们继续学习模块系统。
最后更新:2026-03-27