我建议至少了解Haskell中的类型类。类型类的创建是一种针对操作员重载的规范方法,但它发现了其他用途,并在一定程度上使Haskell成为了它。
例如,这是临时重载的示例(不是很有效的Haskell):
(==) :: Int -> Int -> Bool
x == y = ...
x /= y = not (x == y)
(==) :: Char -> Char -> Bool
x == y = ...
x /= y = not (x == y)
这是使用类型类重载的相同示例:
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x /= y = not (x == y)
instance Eq Int where
x == y = ...
instance Eq Char where
x == y = ...
这样做的缺点是,你必须拿出你所有的类型类时髦的名字(例如在Haskell,你有相当抽象的Monad
,Functor
,Applicative
还有更简单,更容易识别Eq
,Num
和Ord
)。
一个好处是,一旦您熟悉类型类,便知道如何在该类中使用任何类型。另外,很容易保护未实现所需类的类型的函数,例如:
group :: (Eq a) => [a] -> [[a]]
group = groupBy (==)
编辑:在Haskell中,如果您想要一个==
接受两种不同类型的运算符,则可以使用多参数类型类:
class Eq a b where
(==) :: a -> b -> Bool
(/=) :: a -> b -> Bool
x /= y = not (x == y)
instance Eq Int Int where
x == y = ...
instance Eq Char Char where
x == y = ...
instance Eq Int Float where
x == y = ...
当然,这可能不是一个好主意,因为它明确允许您比较苹果和橙子。但是,您可能需要考虑+
,因为在某些情况下,将a添加Word8
到true Int
确实是明智的。