类型类#

声明#

class <typeClass> <typeVariable> where
    <functionDeclaration>
    ...
  • 类型类:约束类型的接口,同一类型类下的类型具有相同行为、能使用该类型类下所定义的方法;

    class Eq a where
        (==) :: a -> a -> Bool -- 任何属于 'Eq' 类型类的成员
        (/=) :: a -> a -> Bool -- 都可使用这两个函数
    
  • 语法格式:

    • class关键字定义一个类型类;
    • 类型类名称需大写字母开头;
    • 类型变量表示该类型类的成员,使用小写字母;
    • where关键字定义类型类体;
    • 类型类体即一系列函数声明,不需要定义函数体;
  • deriving关键字可自动将数据类型转换为类型类的实例,使得该数据类型能使用类型类下定义的方法;

 1-- | 命令式语言类似的布尔值:
 2-- 非空为 'False',否则为 'True'。
 3-- 'YesNo' 类型类的实例成员都能使用该类型类下定义的函数。
 4class YesNo a where
 5    yesno :: a -> Bool
 6
 7-- | '0' 为 'False',否则为 'True'。
 8instance YesNo Int where
 9    yesno 0 = False
10    yesno _ = True
11
12-- | 空列表为 'False',否则为 'True'。
13instance YesNo [a] where
14    yesno [] = False
15    yesno _  = True
16
17-- | 'id' 函数按原样返回接受到的值。
18instance YesNo Bool where
19    yesno = id
20
21exp1 = yesno (0 :: Int) -- False
22exp2 = yesno ""         -- False
23exp3 = yesno []         -- False
24exp4 = yesno "alice"    -- True

实例#

instance <typeClass> <type> where
    <functionBodies>
    ...
  • 类型类的实例享用类型类定义的方法;
  • 语法格式:
    • instance关键字定义类型类实例;
    • 类型类为被派生的类型类;
    • 类型指定该类型为类型类实例/成员;
    • where关键字定义实例体;
    • 实例体即一系列函数体,指定该类型该如何执行函数;
  • 部分应用:类型类的实质也是函数,经过柯里化,因此可以接受少于形参数量的实参,实现部分应用;
  • 类型类实例支持模式匹配;
 1data TrafficLight = Red | Yellow | Green
 2
 3instance Show TrafficLight where
 4    show Red    = "Red light"
 5    show Yellow = "Yellow light"
 6    show Green  = "Green light"
 7
 8instance Eq TrafficLight where
 9    Red    == Red    = True
10    Yellow == Yellow = True
11    Green  == Green  = True
12    _      == _      = False
13
14exp1 = Red          -- Red light
15exp2 = Green        -- Yellow light
16exp3 = Red == Green -- False
17exp4 = Red `elem` [Red, Yellow, Green] -- True

类型约束#

instance (<typeClass> <typeVariable>, ...) => <type> where
 1infixr 5 :^:
 2data Tree a = Leaf a | Tree a :^: Tree a
 3    deriving (Show, Read)
 4
 5-- | 'a' 是 'Eq' 的成员,同时也是 'Tree' 的成员。
 6-- 同时,'Tree' 本身也属于 'Eq'。
 7instance Eq a => Eq (Tree a) where
 8    Leaf a  == Leaf b  = a == b
 9    m :^: n == x :^: y = m == x && n == y
10    _       == _       = False
11
12-- | 同上。
13instance Ord a => Ord (Tree a) where
14    Leaf a  <= Leaf b  = a <= b
15    Leaf a  <= m :^: n = True
16    m :^: n <= Leaf a  = False
17    m :^: n <= x :^: y = m < x || m == x && n <= y
18
19exp1 = Leaf 1 :^: Leaf 2 :^: Leaf 3
20       -- Leaf 1 :^: (Leaf 2 :^: Leaf 3)
21exp2 = Leaf 1 :^: Leaf 2 <= Leaf 1 :^: Leaf 3 -- True
22exp3 = Leaf 5 <= Leaf 2 :^: Leaf 3            -- True

种类#

<type> :: <kind>
  • 种类:类型构造器的类型;

  • GHCi 中使用:kind命令可查看类型构造器的种类;

  • 语法格式:

    • *:该类型为具体类型,不接受类型参数;

      Int :: *       -- 'Int' 为具体类型
      Maybe Int :: * -- 'Maybe Int' 同上
      
    • P -> Q:接受一个类型P,返回一个类型Q

      Maybe :: * -> * -- 接受一个具体类型(Int)
                      -- 并返回具体类型(Maybe Int)
      Either :: * -> * -> *   -- 接受两个
      Either String :: * -> * -- 部分应用
      (->) :: * -> * -> *