发布于 

类型,类型类

类型,类型类

没想到就写一个类型类,就写了这么多。。。。

参考书籍: Learn you a Haskell

常见类型

大多数与C中相似,但是开头字母必须大写,包含以下类型:

1
Int, Integer, Float, Double, Bool, Char
其中,Int在64位系统下为64位。而Integer则是高精度整型,无穷大。

在Haskell中,元组也算一种特殊的类型,其类型取决于其中的项的数目和种类。理论上项的数目可以无限多,但实际最多62个。

类型变量

当我们想要写一个取出列表第一个元素的函数,并且可以同时应用于多种不同类型的列表时,我们会怎么做呢?在C++中,我们会用模板(Template),而在Haskell中,我们就要用到类型变量了。

比如,我们上述的函数类型便如下:

1
head :: [a] -> a
这里的a,就是一个类型变量了。在这里,a可以是任何类型,只需保证所有的a是同一种类型便可以了。我们还可以使用其他的变量名,不过一般都会使用a,b,c...

比如,fst可以取出一个序对中的第一个元素,其类型如下:

1
fst :: (a,b) -> a

类型类入门

类型类(typeclass)是定义行为的接口。如果一个类型是某类型类的示例(instance),那它必实现了该类型类所描述的行为。

定义念完了,但还是不太明白。那我们可以举一个例子如下:

首先,我们都知道在Haskell中,==为一个函数,那么,他的类型是什么呢:

1
(==) :: (Eq a) => a -> a -> Bool
在这里,我们接触了一个新的符号=>,它的左侧叫做类型约束(type constraint),表示下面的a类型属于Eq这种类型类。它指明了下面的a类型支持比较操作。通俗的说类型类便是"类型的类型",虽然不是很准确。

下面,是各种常见的类型类。

Eq

前面已经提到了,Eq类型类用于判断相等性的类型,要求它的示例必须实现==\=两个函数。在类型约束中用Eq进行约束,就能确保约束的类型能够进行比较操作。 ### Ord 用于可以比较大小的类型。除了函数以外,我们目前所谈到的所有类型都是Ord的实例。 ### Show Show类型类的实例为可以表示为字符串的类型。到目前为止,我们常用的类型中除函数外都为Show类型类的示例。能够操作Show类型类的实例的函数中,最常用的是show。功能是将该实例转为字符串:

1
2
3
4
5
--此处为交互模式
ghci> show 3
"3"
ghci> show 5.334
"5.334"
### Read Read可以是为Show的反例。同样,除函数外我们提到的所有类型均为Read的实例。它可以将字符串类型转为Read的某个实例类型。
1
2
3
4
ghci> read "True" || False
True
ghci> read "8.2" + 3.8
12.0
但是,当我们在写Read "4"这样的语句时,Read将会不知道4该被转化为哪种类型,所以此时我们便应这样写:
1
2
3
4
ghci> read "4" :: Int
4
ghci> read "[1,2,3,4]" :: [Float]
[1.0,2.0,3.0,4.0]
不过,当我们像这样写时:

1
2
3
4
gchi> read "4" + 5
9
ghci> read "[1,2,3,4]" ++ [3]
[1,2,3,4,3]

因为Haskell可以根据后面判断,所以不需标注。 ### Enum Enum的实例类型都是由连续顺序的--他们的值都是可以枚举的。其主要特点在于支持succpred函数,分别为后继(successer)前缀(predecesor)。包含的类型主要有(),Bool,Char,Ordering,Int,Integer,FloatDouble

1
2
3
4
5
6
7
ghci> ['a'..'e']
"abcde"
ghci> [LT .. GT]
[LT,EQ,GT]
--Ordering类型,只包括LT,EQ,GT三种值,分别代表小于,等于,大于。
ghci> succ 'B'
'C'
### Bounded Bounded类型类的类型实例都有一个上限和下限,分别可以用maxBoundminBound来取得。
1
2
3
4
ghci> minBound :: Int
-2147483648
ghci> maxBound :: Char
'\1114111'
minBoundmaxBound两个函数都很有趣,类型为(Bounded a) => a,他们都是多态常量(polymorphic constant)。 ### Num Num是一个表示数值的类型类,它的实例都具有数的特征。比如,一个数的类型:
1
20 :: (Num t) => t
所有的数都是多态常量,它可以具有任何Num类型类中的实例类型的特征,如Int,Integer,Float,Double.
1
2
3
4
ghci> 20 :: Int
20
ghci> 20 :: Float
20.0
在这里,我们可以检查一下运算符的类型:
1
(*) :: (Num a) => a -> a -> a
### Floating Floating只包含两种类型FloatDouble。需要用到Floating类型类的函数一般都是需要用到浮点数来进行某种计算的,如sin,cossqrt。 ### Integeral Integeral仅包含Int,Integer。与其相关的一个函数很有用,叫fromIntegeral。其类型如下:
1
fromIntegeral :: (integeral a, Num b) => a -> b
这个函数能够取一个整数,返回一个更为通用的Num类型类的实例,因为Haskell中浮点型与整型不能直接相加,所以此函数用处很大。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Songer](https://blog.songer.xyz/) 创建,使用 Stellar 作为主题。