系列文章
- 《Haskell趣學指南》筆記之基本語法
- 《Haskell趣學指南》筆記之型別(type)
- 《Haskell趣學指南》筆記之函式
- 《Haskell趣學指南》筆記之高階函式
- 《Haskell趣學指南》筆記之模組
- 《Haskell趣學指南》筆記之自定義型別
這本書居然沒有告訴我怎麼加註釋,我自己搜了一下
- 單行註釋以
--
開頭 - 多行註釋用
{- whatever -}
括起來
繼續看書
顯式型別宣告
: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 複製程式碼
基本型別
- Int -- 有界
- Integer -- 無界,可以存超大整數,效率比 Int 低
- Float / Double / Bool / Char / String就是[Char]
- tuple 的型別由其內部的元素型別決定,空 tuple 是一個單獨的型別,只有一個值
()
型別變數(類似於泛型)
- 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']
-- "abcde"[LT..GT]
-- [LT, EQ, 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