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