Haskell类型和Type类
Haskell是一种函数语言,它是严格类型化的,Haskell编译器在编译时知道整个应用程序中使用的数据类型。
1. 内置类型类
在Haskell中,每个语句都被视为数学表达式,并且此表达式的类别称为类型(Type
)。可以说Type
是在编译时使用的表达式的数据类型。
要了解有关类型的更多信息,可以使用:t
命令。以通用的方式可以将类型视为值,而可以将类型类视为一组相似类型的类型。在本章中,我们将学习不同的内置类型。
2. Int
Int
是代表Integer
类型数据的类型类。2147483647
到-2147483647
范围内的每个整数都属于Int
类型类。在下面的示例中,函数fType()
将根据定义的类型来表示。
fType :: Int -> Int -> Int
fType x y = x*x + y*y
main = print (fType 2 4)
在这里,我们将函数fType()
的类型设置为int
。函数采用两个int
值,并返回一个int
值。如果编译并执行这段代码,那么它将产生以下输出:
sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts
sh-4.3$ main
20
3. Integer
Integer
可以视为Int
的超集。此值不受任何数字限制,因此Integer
可以是任何长度,没有任何限制。要了解Int
和Integer
类型之间的基本区别,修改上面的代码如下所示:
fType :: Int -> Int -> Int
fType x y = x*x + y*y
main = print (fType 212124454 44545454454554545445454544545)
如果编译以上代码,将抛出以下错误消息:
main.hs:3:31: Warning:
Literal 44545454454554545445454544545 is out of the Int range -
9223372036854775808..9223372036854775807
Linking main ...
发生此错误是因为函数fType()
期望一个Int
类型值,并且传递了一些大的Int
类型值。为了避免此错误,将Int
修改类型Integer
并观察区别。
fType :: Integer -> Integer -> Integer
fType x y = x*x + y*y
main = print (fType 212124454 4454545445455454545445445454544545)
现在,它将产生以下输出:
sh-4.3$ main
1984297512562793395882644631364297686099210302577374055141
4. Float
看看下面的代码,它显示了Float
类型如何在Haskell中工作:
fType :: Float -> Float -> Float
fType x y = x*x + y*y
main = print (fType 2.5 3.8)
该函数将两个浮点值作为输入,并产生另一个浮点值作为输出。当编译并执行此代码时,它将产生以下输出:
sh-4.3$ main
20.689999
5. Double
Double
是浮点数,它的末尾具有双精度。看下面的示例代码:
fType :: Double -> Double -> Double
fType x y = x*x + y*y
main = print (fType 2.56 3.81)
当编译并执行此代码时,它将产生以下输出:
sh-4.3$ main
21.0697
6. Bool
Bool是布尔类型。它的值可以是True
或False
。执行以下代码以了解Bool
类型在Haskell中的工作方式。
main = do
let x = True
if x == False
then putStrLn "X matches with Bool Type"
else putStrLn "X is not a Bool Type"
在这里,我们将变量x
定义为布尔型,并将其与另一个布尔值进行比较以检查其值。当编译并执行此代码时,它将产生以下输出:
sh-4.3$ main
X is not a Bool Type
7. Char
Char
代表字符。单引号内的所有内容均视为字符。在下面的代码中,我们修改了前面的fType()
函数以接受Char
值并将Char
值返回为输出。
fType :: Char-> Char
fType x = 'K'
main = do
let x = 'v'
print (fType x)
上面的代码将调用fType()
函数,参数为char
类型值为v
,但它将返回另一个char
值,即K
。下面是它的输出:
sh-4.3$ main
'K'
请注意,不用显式使用这些类型,因为Haskell足够聪明,可以在声明类型之前捕获类型。在本教程的后续章节中,我们将了解不同的类型和类型类如何使Haskell成为强类型语言。
8. EQ类型类
EQ类型类是提供测试表达式是否相等的功能的接口。检查表达式是否相等的类型类都应属于此EQ类型类。
上面提到的所有标准类型类都是此EQ类的一部分。每当我们使用上述任何一种类型检查任何相等性时,实际上都是在调用EQ类型类。
在以下示例中,在内部使用==
或/=
操作使用EQ类型。
main = do
if 8 /= 8
then putStrLn "The values are Equal"
else putStrLn "The values are not Equal"
它将产生以下输出:
sh-4.3$ main
The values are not Equal
9. Ord类型类
Ord是另一个提供排序功能的接口类。到目前为止,使用的所有类型都是Ord
接口的一部分。与EQ接口类似,可以使用>
,<
,<=
,>=
,compare
来调用Ord接口。
在下面示例中使用此类型类的“比较”功能。
main = print (4 <= 2)
在这里,Haskell编译器将检查4
是否小于或等于2
。由于4
不是小于或等于2
,因此代码将产生以下输出:
sh-4.3$ main
False
10. Show
Show
具有将参数打印为字符串的功能。无论参数是什么,它始终将结果打印为字符串。在以下示例中,我们将使用此界面打印整个列表。Show
可用于调用此接口。
main = print (show [1..10])
它将在控制台上产生以下输出。在这里,双引号表示它是字符串类型的值。
sh-4.3$ main
"[1,2,3,4,5,6,7,8,9,10]"
11. Read
Read
接口的功能与显示相同,但不会以字符串格式打印结果。在以下代码中,使用read
接口读取字符串值并转换为Int
值。
main = print (readInt "12")
readInt :: String -> Int
readInt = read
在这里,将字符串变量("12"
)传递给readInt
方法,该方法在转换后又返回12
(Int值)。下面是它的输出:
sh-4.3$ main
12
12. Enum
枚举是Type
类的另一种类型,可在Haskell中启用顺序或有序功能。可以通过诸如Succ
,Pred
,Bool
,Char
等命令访问此Type
类。
以下代码显示了如何查找12
的后继值:
main = print (succ 12)
它将在控制台上产生以下输出:
sh-4.3$ main
13
13. Bounded
具有上限和下限的所有类型都属于此Type
类。例如,Int
类型数据的最大范围为9223372036854775807
,最小范围为-9223372036854775808
。
以下代码显示Haskell如何确定Int
类型的最大和最小范围。
main = do
print (maxBound :: Int)
print (minBound :: Int)
它将在控制台上产生以下输出:
sh-4.3$ main
9223372036854775807
-9223372036854775808
您可以尝试查找Char
,Float
和Bool
类型的最大和最小界限。
14. Num
Num
类型类用于数字运算。诸如Int
,Integer
,Float
和Double
之类的类型都属于此Type
类。看一下下面的代码-
main = do
print(2 :: Int)
print(2 :: Float)
它将在控制台上产生以下输出:
sh-4.3$ main
2
2.0
15. Integral
整数可以视为Num Type
类的子类。Num Type
类保存所有类型的数字,而Integral
类型类仅用于整数。Int
和Integer
是此Type
类下的类型。
16. Floating
像Integral
一样,Floating
也是Num Type
类的一部分,但它仅包含浮点数。因此,Float
和Double
属于此类类型。
17. 自定义Type类
与任何其他编程语言一样,Haskell允许开发人员定义用户定义的类型。在下面的示例中,我们将创建一个用户定义的类型并使用它。
data Area = Circle Float Float Float
surface :: Area -> Float
surface (Circle _ _ r) = pi * r ^ 2
main = print (surface $ Circle 10 20 10 )
在这里,创建了一个名为Area
的新类型。接下来使用这个类型来计算圆的面积。在上面的示例中,surface
是一个函数,该函数将Area
作为输入并产生Float
作为输出。
请记住,data
在此处是关键字,Haskell中所有用户定义的类型始终以大写字母开头。
它将产生以下输出:
sh-4.3$ main
314.15927