📜  Haskell-类型和类型类

📅  最后修改于: 2020-11-04 06:56:52             🧑  作者: Mango


Haskell是一种功能语言,它是严格类型化的,这意味着编译器将在编译时知道整个应用程序中使用的数据类型。

内置类型类

在Haskell中,每个语句都被视为数学表达式,并且此表达式的类别称为Type 。您可以说“ Type”是在编译时使用的表达式的数据类型。

要了解有关Type的更多信息,我们将使用“:t”命令。以通用的方式,可以将Type视为值,而可以将Type Class视为一组相似类型的Type。在本章中,我们将学习不同的内置类型。

整数

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

整数

整数可以视为Int的超集。此值不受任何数字限制,因此Integer可以是任何长度,没有任何限制。要查看IntInteger类型之间的基本区别,让我们如下修改上述代码-

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类型值。为避免此错误,让我们用“ Integer”修改类型“ Int”并观察其区别。

fType :: Integer -> Integer -> Integer 
fType x y = x*x + y*y 
main = print (fType 212124454 4454545445455454545445445454544545) 

现在,它将产生以下输出-

sh-4.3$ main
1984297512562793395882644631364297686099210302577374055141

浮动

看一下下面的代码。它显示了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 

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

布尔

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 

烧焦

字符代表字符。单引号内的所有内容均视为字符。在以下代码中,我们修改了先前的fType()函数以接受Char值并返回Char值作为输出。

fType :: Char-> Char 
fType x = 'K' 
main = do  
   let x = 'v' 
   print (fType x) 

上面的代码将调用char类型值为“ v”的fType()函数,但它将返回另一个char值,即“ K”。这是它的输出-

sh-4.3$ main 
'K'

注意,我们将不会显式使用这些类型,因为Haskell足够聪明,可以在声明类型之前捕获该类型。在本教程的后续章节中,我们将了解不同的类型和Type类如何使Haskell成为强类型语言。

情商类型类别

EQ类型类是提供测试表达式是否相等的功能的接口。任何要检查表达式是否相等的Type类都应属于此EQ Type类。

上面提到的所有标准Type类都是此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 

Ord类型类别

Ord是另一个提供给我们订购功能的接口类。到目前为止,我们使用的所有类型都是该Ord接口的一部分。与EQ接口类似,可以使用“>”,“ <”,“ <=”,“> =”,“比较”来调用Ord接口。

请在下面的示例中找到我们使用此Type类的“比较”功能的示例。

main = print (4 <= 2) 

在这里,Haskell编译器将检查4是否小于或等于2。由于不是,因此代码将产生以下输出-

sh-4.3$ main 
False

显示

Show具有将其参数打印为字符串的功能。无论其参数是什么,它始终将结果打印为字符串。在以下示例中,我们将使用此界面打印整个列表。 “显示”可用于调用此界面。

main = print (show [1..10]) 

它将在控制台上产生以下输出。在这里,双引号表示它是字符串类型的值。

sh-4.3$ main 
"[1,2,3,4,5,6,7,8,9,10]" 

读取界面的功能与显示相同,但不会以字符串格式打印结果。在下面的代码中,我们使用read接口读取字符串值并将其转换为Int值。

main = print (readInt "12") 
readInt :: String -> Int 
readInt = read 

在这里,我们将String变量(“ 12”)传递给readInt方法,该方法在转换后又返回12(Int值)。这是它的输出-

sh-4.3$ main 
12

枚举

枚举是Type类的另一种类型,可在Haskell中启用顺序或有序功能。可以通过诸如Succ,Pred,Bool,Char等命令访问此Type类。

以下代码显示如何查找12的后继值。

main = print (succ 12) 

它将产生以下输出-

sh-4.3$ main
13

有界

具有上限和下限的所有类型都属于此Type类。例如, Int类型数据的最大范围为“ 9223372036854775807”,最小范围为“ -9223372036854775808”。

以下代码显示Haskell如何确定Int类型的最大和最小范围。

main = do 
   print (maxBound :: Int) 
   print (minBound :: Int) 

它将产生以下输出-

sh-4.3$ main
9223372036854775807
-9223372036854775808

现在,尝试查找Char,Float和Bool类型的最大和最小界限。

数词

此类型类用于数字运算。诸如Int,Integer,Float和Double之类的类型都属于此Type类。看一下下面的代码-

main = do 
   print(2 :: Int)  
   print(2 :: Float) 

它将产生以下输出-

sh-4.3$ main
2
2.0

积分

整数可以视为Num类型类的子类。 Num Type类保留所有类型的数字,而Integral类型类仅用于整数。 Int和Integer是此Type类下的类型。

漂浮的

像Integral一样,Floating也是Num Type类的一部分,但它仅包含浮点数。因此, FloatDouble属于此类类型。

自定义类型类

与任何其他编程语言一样,Haskell允许开发人员定义用户定义的类型。在下面的示例中,我们将创建一个用户定义的类型并使用它。

data Area = Circle Float Float Float  
surface :: Area -> Float   
surface (Circle _ _ r) = pi * r ^ 2   
main = print (surface $ Circle 10 20 10 ) 

在这里,我们创建了一个名为Area的新类型。接下来,我们使用这种类型来计算圆的面积。在上面的示例中,“表面”是一个函数,将Area作为输入,并生成Float作为输出。

请记住,“数据”是此处的关键字,Haskell中所有用户定义的类型始终以大写字母开头。

它将产生以下输出-

sh-4.3$ main
314.15927