欢迎访问宙启技术站
智能推送

Haskell中的类型类和多态性

发布时间:2023-12-09 15:23:02

Haskell是一种纯函数式编程语言,其类型系统非常强大。在Haskell中,类型类和多态性是两个非常重要的概念。

类型类用于定义一组相关类型的通用行为。它类似于面向对象编程中的接口或者Java中的泛型。通过使用类型类,我们可以定义一些通用的函数或者操作符,并使这些函数或操作符能够用于多种类型。

比如,考虑下面这个例子,我们定义了一个类型类Showable,它包含一个函数show,这个函数接受一个参数并返回一个字符串表示该参数的内容。

class Showable a where
  show :: a -> String

然后我们可以为一些类型实现Showable类型类:

instance Showable Int where
  show = show

instance Showable Bool where
  show True = "True"
  show False = "False"

接着,我们可以定义一个通用的函数printShowable,它接受一个实现了Showable类型类的参数,并将其内容打印出来:

printShowable :: Showable a => a -> IO ()
printShowable x = putStrLn (show x)

通过这样定义,我们可以对任意实现了Showable的类型使用printShowable函数:

main :: IO ()
main = do
  printShowable (3 :: Int) -- 输出 3
  printShowable True -- 输出 True

这里的:: Int用于明确指定3的类型为Int,因为Haskell推断出的默认类型为Integer

多态性则是指函数或者操作符可以用于多种类型的参数。在Haskell中,有两种形式的多态性:parametric polymorphism和ad-hoc polymorphism。

parametric polymorphism是指函数或者操作符可以适用于任意类型的参数。比如,考虑下面这个函数length,它返回一个列表的长度:

length :: [a] -> Int
length [] = 0
length (_:xs) = 1 + length xs

main :: IO ()
main = do
  print (length [1, 2, 3]) -- 输出 3
  print (length ["hello", "world"]) -- 输出 2

这里的a是一个类型变量,可以表示任意类型。因此,length函数可以适用于任意类型的列表。

ad-hoc polymorphism是指函数或者操作符在不同类型参数上有不同的行为。这通过类型类来实现。我们在之前的例子中已经见过了Showable这个类型类的例子。

class Eq a where
  (==) :: a -> a -> Bool

instance Eq Int where
  (==) = (==)

instance Eq Bool where
  (==) = (==)

main :: IO ()
main = do
  print (3 == 3) -- 输出 True
  print (True == False) -- 输出 False

这里我们定义了一个类型类Eq,它包含一个函数==,这个函数接受两个参数并返回一个布尔值。然后我们为IntBool类型实现了Eq类型类,分别使用了==操作符的实现。

通过这样定义,我们可以对任意实现了Eq的类型使用==操作符。