《Haskell趣學指南》筆記之類型(type)

系列文章bash


這本書竟然沒有告訴我怎麼加註釋,我本身搜了一下函數

  • 單行註釋以 -- 開頭
  • 多行註釋用 {- whatever -} 括起來

繼續看書post

顯式類型聲明

  • :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
相關文章
相關標籤/搜索