您可能听说过 kinds,它们是 Haskell 中的“类型的类型”。类型是一种类型为* 的东西,它表示可以有值的东西:
> :kind Int
Int :: *
> :kind Char
Char :: *
类型构造函数是类型为* -> * 的东西;类型构造函数接受一个类型(* 之类的东西)并返回另一种类型。
> :kind Maybe
Maybe :: * -> *
> :kind []
[] :: * -> *
应用类型构造函数为您提供了一种新事物*:
> :kind Maybe Int
Maybe Int :: *
> :kind [] Float
[] Float :: *
(解析器允许[Foo] 作为[] Foo 的特例。)
还有其他种类的东西。其中之一是Constraint,您可以使用约束构造函数(也称为类型类)创建Constraint。给一个约束构造函数一个类型,你就会得到一个约束。
> :kind Show
Show :: * -> Constraint
> :kind Show Int
Show Int :: Constraint
> :kind Show (Int -> Char)
Show (Int -> Char) :: Constraint
(请注意,即使没有定义 Int -> Char 的实例,后者也是正确的。)
从这个角度来看,=> 看起来像一个运算符,而不仅仅是特殊的语法。它的参数是一个约束的“列表”(尽管使用普遍量化的类型变量而不是具体类型)和一个类型,它的返回值是一个“约束”类型(假设除了@987654336 之外还有一种ConstrainedType @、* -> * 和 Constraint)。
:t show
show :: Show a => a -> String
-- Taking extreme liberties with syntax
-- :k (=>)
-- (=>) :: [Constraint] -> * -> ConstrainedType
-- A section?
-- :k (Show a =>)
-- (Show a =>) :: * -> ConstrainedType
-- :k (Showa => * -> String)
-- Show a => a -> String :: ConstrainedType