《Haskell趣學指南》筆記之型別(type)
摘要:
:t <exp>
可以得到對應的型別
型別是大寫字母開頭的
給單引數函式宣告型別,語法是:: ParamType -> ReturnType
removeNonUppercase :: [Char] -...
-
:t <exp>
可以得到對應的型別 - 型別是大寫字母開頭的
-
給單引數函式宣告型別,語法是
:: ParamType -> ReturnType
removeNonUppercase :: [Char] -> [Char] removeNonUppercase st = [ c | c <- st, c ` elem` ['A'..' Z']] 複製程式碼
-
給多引數函式宣告型別,語法是
:: Param1Type -> Param2Type ->ReturnType
addThree :: Int -> Int -> Int -> Int addThree x y z = x + y + z 複製程式碼
基本型別
()
型別變數(類似於泛型)
-
head 的型別是
head :: [a] -> a
- 注意這裡的 a 是小寫,不是大寫,因為 a 是型別變數,不是型別
- 一般型別變數只使用一個字母,但是用多個字母也不報錯
- 多型函式:使用了型別變數的函式。
型別類 typeclass
- 類似於介面,但是它是用來約束型別 type 的。
- 一個 type 可以是多個 typeclass 的例項,一個 typeclass 可以有多個 type 例項。
-
Eq 是最常見的型別類,Haskell 中標準型別都是 Eq 的例項,Eq 要求它的例項必須實現
==
和/=
兩個函式 -
我們可以看看
==
運算子(也是函式)的型別ghci> :t (==) (==) :: (Eq a) => a -> a -> Bool 複製程式碼
-
看上面程式碼,型別宣告
a->a->Bool
前面有個=>
,再前面有個(Eq a)
-
這個
(Eq a)
叫做型別約束 -
它約束 a 必須是 Eq 的例項,這樣就保證了 a 必須實現
==
函式,以提供給全域性的==
函式呼叫
-
這個
-
Ord 型別類要求例項必須實現
< / <= / > / >=
等比較操作 -
Ord 的有三種值:GT / LT / EQ,可以用 compare 得到
ghci> compare 1 2 LT 複製程式碼
- Show 型別類要求例項可以表示為字串
- show 函式可以把任意 Show 例項變為字串
- Read 型別類跟 Show 相反,它把非字串的東西轉為字串
-
read 函式是 show 的相反操作
ghci> show True "True" ghci> (read "True") || False True 複製程式碼
-
注意直接
read "True"
會報錯,因為 GHCi 需要根據後續的操作來確定你要把字串轉成什麼型別 -
型別註解:可以使用型別註解來告訴 GHCi 這玩意是什麼型別。
read "True" :: Bool
就不會報錯,看起來很像 TypeScript 的 as 關鍵字 - Enum 型別類要求例項有 successer 後繼和 predecesor 前趨兩個操作。可以使用 succ 函式和 pred 函式得到一個例項的後繼和前驅。
-
Enum 的例子
['a' .. 'e'] [LT..GT]
- Bounded 型別類要求例項有上限和下限
- 用 maxBound 和 minBound 可以獲取例項的上下限
-
這兩個函式的型別是
(Bounded a)=> a
,這叫多型常量(跟多型函式對應)。 -
maxBound :: (Bool, Int, Char)
會得到每個例項的上限組成的 tuple,即(True, 2147483647, \1114111)
- Num 型別類要求例項具有數的特徵。
-
:t 20
的結果是(Num t)=> t
- 這很奇怪, 20 的型別居然不是 Int 或者 Integer 或者 Float 之類的,而是這些型別對應的 typeclass 對應的多型常量,有點燒腦。
- 所有的數都是多型常量,可以具有任何 Num 的例項的特徵,也就是說 20 既可以是 Int / Integer 也可以是 Float / Double 等。
- Floating 型別要求例項具有浮點數的特徵,如 Float 和 Double 都是 Floating 的例項。
-
如
sin :: Floating a => a -> a
- Integeral 型別要求例項具有整數的特徵,如 Int 和 Integer。
-
如
fromIntegral :: (Num b, Integral a) => a -> b
-
length [1,2,3] + 3.2
會報錯,解決辦法是fromIntegral (length [12,3]) + 3.2
型別類概覽
- Haskell 中所有標準 type 都是 Eq 的例項,除了輸入輸出相關型別和函式
- 目前我們遇到的所有 type 都是 Ord 的例項,除了函式
- 目前我們遇到的所有 type 都是 Show 的例項,除了函式
- 目前我們遇到的所有 type 都是 Read 的例項,除了函式
- Enum 型別類包含的 type 有 () / Bool / Char / Ordering / Int / Integer / Float / Double
- Bounded 包含的 type 有 Int / Char / Bool 等
- Num 包含 Int / Integer / Float / Double,只有已經屬於 Show 和 Eq 的型別例項,才能成為 Num 的例項,這是一個先決條件( prerequisite)
- Floating 包含 Float / Double
- Integeral 包含 Int / Integer